Commits

James Cook  committed 8ac4ab7

Merge inspectors UI project, gooey-4, into viewer-2 trunk. Added new tooltips to 3D avatars, 2D avatar names, and 3D objects. Refactors tooltips and text boxes, line editors, and text editors. Breaks LLExpandableTextBox, but a fix is coming.

Resolved conflicts in lltexteditor.cpp, llchatitemscontainerctrl.cpp, llchatmsgbox.cpp, llfloaterbuycurrency.cpp, llnearbychat.cpp, floater_buy_currency.xml, and ru/strings.xml

Merging revisions 134925-135157 of svn+ssh://svn.lindenlab.com/svn/linden/branches/gooey/gooey-4 into C:\source\viewer-2.0.0-3, respecting ancestry

  • Participants
  • Parent commits d1c77f6

Comments (0)

Files changed (241)

File indra/integration_tests/llui_libtest/llwidgetreg.cpp

 #include "llcombobox.h"
 #include "llcontainerview.h"
 #include "lliconctrl.h"
+#include "llmenubutton.h"
 #include "llmenugl.h"
 #include "llmultislider.h"
 #include "llmultisliderctrl.h"
 	if (register_widgets)
 	{
 		LLDefaultChildRegistry::Register<LLButton> button("button");
+		LLDefaultChildRegistry::Register<LLMenuButton> menu_button("menu_button");
 		LLDefaultChildRegistry::Register<LLCheckBoxCtrl> check_box("check_box");
 		LLDefaultChildRegistry::Register<LLComboBox> combo_box("combo_box");
 		LLDefaultChildRegistry::Register<LLFilterEditor> filter_editor("filter_editor");

File indra/llcommon/llpreprocessor.h

 #if defined(LL_WINDOWS)
 #define BOOST_REGEX_NO_LIB 1
 #define CURL_STATICLIB 1
+#ifndef XML_STATIC
 #define XML_STATIC
+#endif
 #endif	//	LL_WINDOWS
 
 

File indra/llcommon/llsafehandle.h

 	Type*	operator->()						{ return nonNull(mPointer); }
 
 	Type*	get() const							{ return mPointer; }
+	void	clear()								{ assign(NULL); }
 	// we disallow these operations as they expose our null objects to direct manipulation
 	// and bypass the reference counting semantics
 	//const Type&	operator*() const			{ return *nonNull(mPointer); }

File indra/llcommon/llsecondlifeurls.cpp

 #include "llsecondlifeurls.h"
 /*
 const std::string CREATE_ACCOUNT_URL ( 
-	"http://secondlife.com/registration/");
+	"http://join.secondlife.com/");
 
 const std::string MANAGE_ACCOUNT ( 
 	"http://secondlife.com/account/");  // *TODO: NOT USED

File indra/llcommon/llstringtable.cpp

 
 LLStringTable gStringTable(32768);
 
+LLStringTableEntry::LLStringTableEntry(const char *str)
+: mString(NULL), mCount(1)
+{
+	// Copy string
+	U32 length = (U32)strlen(str) + 1;	 /*Flawfinder: ignore*/
+	length = llmin(length, MAX_STRINGS_LENGTH);
+	mString = new char[length];
+	strncpy(mString, str, length);	 /*Flawfinder: ignore*/
+	mString[length - 1] = 0;
+}
+
+LLStringTableEntry::~LLStringTableEntry()
+{
+	delete [] mString;
+	mCount = 0;
+}
+
 LLStringTable::LLStringTable(int tablesize)
 : mUniqueEntries(0)
 {

File indra/llcommon/llstringtable.h

 class LLStringTableEntry
 {
 public:
-	LLStringTableEntry(const char *str)
-		: mString(NULL), mCount(1)
-	{
-		// Copy string
-		U32 length = (U32)strlen(str) + 1;	 /*Flawfinder: ignore*/
-		length = llmin(length, MAX_STRINGS_LENGTH);
-		mString = new char[length];
-		strncpy(mString, str, length);	 /*Flawfinder: ignore*/
-		mString[length - 1] = 0;
-	}
-	~LLStringTableEntry()
-	{
-		delete [] mString;
-		mCount = 0;
-	}
+	LLStringTableEntry(const char *str);
+	~LLStringTableEntry();
+
 	void incCount()		{ mCount++; }
 	BOOL decCount()		{ return --mCount; }
 

File indra/llcommon/llversionviewer.h

 const S32 LL_VERSION_PATCH = 0;
 const S32 LL_VERSION_BUILD = 0;
 
-const char * const LL_CHANNEL = "Second Life 2009";
+const char * const LL_CHANNEL = "Second Life Developer";
 
 #endif

File indra/llrender/llfontgl.cpp

 	S32 start_of_last_word = 0;
 	BOOL in_word = FALSE;
 
-	F32 scaled_max_pixels =	(F32)llceil(max_pixels * sScaleX);
+	// avoid S32 overflow when max_pixels == S32_MAX by staying in floating point
+	F32 scaled_max_pixels =	ceil(max_pixels * sScaleX);
 
 	S32 i;
 	for (i=0; (i < max_chars); i++)

File indra/llui/CMakeLists.txt

     lllayoutstack.cpp
     lllineeditor.cpp
     lllocalcliprect.cpp
+    llmenubutton.cpp
     llmenugl.cpp
     llmodaldialog.cpp
     llmultifloater.cpp 
     lltextparser.cpp
     lltransientfloatermgr.cpp
     lltransutil.cpp
+    lltoggleablemenu.cpp
     lltooltip.cpp
     llui.cpp
     lluicolortable.cpp
     lllazyvalue.h
     lllineeditor.h
     lllocalcliprect.h
+    llmenubutton.h
     llmenugl.h
     llmodaldialog.h
     llmultifloater.h 
     lltextbox.h
     lltexteditor.h
     lltextparser.h
+    lltoggleablemenu.h
     lltooltip.h
     lltransientfloatermgr.h
     lltransutil.h

File indra/llui/llbutton.cpp

 	mRightHPad(p.pad_right),
 	mHoverGlowStrength(p.hover_glow_amount),
 	mCommitOnReturn(p.commit_on_return),
-	mFadeWhenDisabled(FALSE)
+	mFadeWhenDisabled(FALSE),
+	mForcePressedState(FALSE)
 {
 	static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
 	static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
 	bool enabled = isInEnabledChain();
 
 	bool pressed = pressed_by_keyboard 
-					|| (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y));
+					|| (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y))
+					|| mForcePressedState;
 	bool selected = getToggleState();
 	
 	bool use_glow_effect = FALSE;

File indra/llui/llbutton.h

 	static void		toggleFloaterAndSetToggleState(LLUICtrl* ctrl, const LLSD& sdname);
 	static void		setFloaterToggle(LLUICtrl* ctrl, const LLSD& sdname);
 	static void		showHelp(LLUICtrl* ctrl, const LLSD& sdname);
+
+	void		setForcePressedState(BOOL b) { mForcePressedState = b; }
 	
 protected:
 	const LLPointer<LLUIImage>&	getImageUnselected() const	{ return mImageUnselected; }
 	BOOL						mNeedsHighlight;
 	BOOL						mCommitOnReturn;
 	BOOL						mFadeWhenDisabled;
+	BOOL						mForcePressedState;
 
 	LLFrameTimer				mFlashingTimer;
 };

File indra/llui/llcheckboxctrl.cpp

 
 	LLTextBox::Params tbparams = p.label_text;
 	tbparams.rect(label_rect);
-	tbparams.text(local_label);
+	tbparams.initial_value(local_label);
 	if (p.font.isProvided())
 	{
 		tbparams.font(p.font);

File indra/llui/llcombobox.cpp

 	}
 }
 
-BOOL LLComboBox::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
+BOOL LLComboBox::handleToolTip(S32 x, S32 y, MASK mask)
 {
     std::string tool_tip;
 
-	if(LLUICtrl::handleToolTip(x, y, msg, sticky_rect_screen))
+	if(LLUICtrl::handleToolTip(x, y, mask))
 	{
 		return TRUE;
 	}
 	
 	if( !tool_tip.empty() )
 	{
-		LLToolTipMgr::instance().show(LLToolTipParams()
+		LLToolTipMgr::instance().show(LLToolTip::Params()
 			.message(tool_tip)
 			.sticky_rect(calcScreenRect()));
 	}

File indra/llui/llcombobox.h

 	// LLView interface
 	virtual void	onFocusLost();
 
-	virtual BOOL	handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect);
+	virtual BOOL	handleToolTip(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleKeyHere(KEY key, MASK mask);
 	virtual BOOL	handleUnicodeCharHere(llwchar uni_char);
 

File indra/llui/llconsole.cpp

 const S32 MIN_CONSOLE_WIDTH = 200;
  
 LLConsole::LLConsole(const LLConsole::Params& p) 
-:	LLView(p),
+:	LLUICtrl(p),
 	LLFixedBuffer(p.max_lines),
 	mLinePersistTime(p.persist_time), // seconds
 	mFont(p.font)
 	mConsoleWidth = new_width;
 	mConsoleHeight= new_height;
 	
-	LLView::reshape(new_width, new_height, called_from_parent);
+	LLUICtrl::reshape(new_width, new_height, called_from_parent);
 	
 	for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++)
 	{

File indra/llui/llconsole.h

 #define LL_LLCONSOLE_H
 
 #include "llfixedbuffer.h"
-#include "llview.h"
+#include "lluictrl.h"
 #include "v4color.h"
 #include <deque>
 
-class LLFontGL;
 class LLSD;
 
-class LLConsole : public LLFixedBuffer, public LLView
+class LLConsole : public LLFixedBuffer, public LLUICtrl
 {
 public:
 	typedef enum e_font_size
 		BIG = 1
 	} EFontSize;
 
-	struct Params : public LLInitParam::Block<Params, LLView::Params>
+	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
 		Optional<U32>	max_lines;
 		Optional<F32>	persist_time;

File indra/llui/lldraghandle.cpp

 		LLTextBox::Params params;
 		params.name("Drag Handle Title");
 		params.rect(getRect());
-		params.text(trimmed_title);
+		params.initial_value(trimmed_title);
 		params.font(font);
 		params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT | FOLLOWS_RIGHT);
 		params.font_shadow(LLFontGL::DROP_SHADOW_SOFT);
 }
 
 
-const std::string& LLDragHandleTop::getTitle() const
+std::string LLDragHandleTop::getTitle() const
 {
 	return mTitleBox == NULL ? LLStringUtil::null : mTitleBox->getText();
 }
 }
 
 
-const std::string& LLDragHandleLeft::getTitle() const
+std::string LLDragHandleLeft::getTitle() const
 {
 	return LLStringUtil::null;
 }
 		getRect().getWidth() - LEFT_PAD - RIGHT_PAD,
 		title_height);
 
-	mTitleBox->setRect( title_rect );
+	// calls reshape on mTitleBox
+	mTitleBox->setShape( title_rect );
 }
 
 void LLDragHandleTop::reshape(S32 width, S32 height, BOOL called_from_parent)

File indra/llui/lldraghandle.h

 	void			setTitleVisible(BOOL visible);
 
 	virtual void	setTitle( const std::string& title ) = 0;
-	virtual const std::string&	getTitle() const = 0;
+	virtual std::string	getTitle() const = 0;
 
 	virtual BOOL	handleHover(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 	friend class LLUICtrlFactory;
 public:
 	virtual void	setTitle( const std::string& title );
-	virtual const std::string& getTitle() const;
+	virtual std::string getTitle() const;
 	virtual void	draw();
 	virtual void	reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 
 	friend class LLUICtrlFactory;
 public:
 	virtual void	setTitle( const std::string& title );
-	virtual const std::string& getTitle() const;
+	virtual std::string getTitle() const;
 	virtual void	draw();
 	virtual void	reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 

File indra/llui/llfloater.cpp

 	}
 }
 
-const std::string& LLFloater::getCurrentTitle() const
+std::string LLFloater::getCurrentTitle() const
 {
 	return mDragHandle ? mDragHandle->getTitle() : LLStringUtil::null;
 }

File indra/llui/llfloater.h

 	LLMultiFloater* getHost();
 
 	void			applyTitle();
-	const std::string&	getCurrentTitle() const;
+	std::string		getCurrentTitle() const;
 	void			setTitle( const std::string& title);
 	std::string		getTitle() const;
 	void			setShortTitle( const std::string& short_title );

File indra/llui/llfocusmgr.cpp

 // Returns TRUE is parent or any descedent of parent is the mouse captor.
 BOOL LLFocusMgr::childHasMouseCapture( const LLView* parent ) const
 {
-	if( mMouseCaptor && mMouseCaptor->isView() )
+	if( mMouseCaptor && dynamic_cast<LLView*>(mMouseCaptor) != NULL )
 	{
 		LLView* captor_view = (LLView*)mMouseCaptor;
 		while( captor_view )

File indra/llui/lllayoutstack.cpp

 #include "linden_common.h"
 
 #include "lllayoutstack.h"
+
 #include "lllocalcliprect.h"
+#include "llpanel.h"
 #include "llresizebar.h"
 #include "llcriticaldamp.h"
 

File indra/llui/lllayoutstack.h

 #ifndef LL_LLLAYOUTSTACK_H
 #define LL_LLLAYOUTSTACK_H
 
-#include "llpanel.h"
+#include "llview.h"
+
+class LLPanel;
 
 class LLLayoutStack : public LLView
 {

File indra/llui/lllineeditor.cpp

 	highlight_color("highlight_color"),
 	preedit_bg_color("preedit_bg_color"),
 	border(""),
-	is_unicode("is_unicode"),
-	drop_shadow_visible("drop_shadow_visible"),
-	border_drop_shadow_visible("border_drop_shadow_visible"),
 	bg_visible("bg_visible"),
 	text_pad_left("text_pad_left"),
 	text_pad_right("text_pad_right"),
 	{
 		return TRUE;
 	}
-	if (mSelectAllonFocusReceived
-		&& gFocusMgr.getKeyboardFocus() != this)
-	{
-		setFocus( TRUE );
-	}
-	else
+	
+	if (!mSelectAllonFocusReceived
+		|| gFocusMgr.getKeyboardFocus() == this)
 	{
 		mLastSelectionStart = -1;
 		mLastSelectionStart = -1;
 
-		setFocus( TRUE );
-
 		if (mask & MASK_SHIFT)
 		{
 			// Handle selection extension
 		gFocusMgr.setMouseCapture( this );
 	}
 
+	setFocus(TRUE);
+
 	// delay cursor flashing
 	mKeystrokeTimer.reset();
 	

File indra/llui/lllineeditor.h

 		Optional<S32>					text_pad_left,
 										text_pad_right;
 
-		Ignored							is_unicode,
-										drop_shadow_visible,	
-										border_drop_shadow_visible,
-										bg_visible;
+		Ignored							bg_visible;
 		
 		Params();
 	};
 	virtual void	getPreeditRange(S32 *position, S32 *length) const;
 	virtual BOOL	getPreeditLocation(S32 query_position, LLCoordGL *coord, LLRect *bounds, LLRect *control) const;
 	virtual S32		getPreeditFontSize() const;
+	virtual LLWString getPreeditString() const { return getWText(); }
 
 protected:
 	LLUIString		mText;					// The string being edited.

File indra/llui/llmenubutton.cpp

+/** 
+ * @file llbutton.cpp
+ * @brief LLButton base class
+ *
+ * $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$
+ */
+
+#include "linden_common.h"
+
+#include "llmenubutton.h"
+
+// Linden library includes
+#include "llmenugl.h"
+#include "llstring.h"
+#include "v4color.h"
+
+static LLDefaultChildRegistry::Register<LLMenuButton> r("menu_button");
+
+
+LLMenuButton::Params::Params()
+:	menu_filename("menu_filename")
+{
+}
+
+
+LLMenuButton::LLMenuButton(const LLMenuButton::Params& p)
+:	LLButton(p),
+	mMenu(NULL),
+	mMenuVisibleLastFrame(false)
+{
+	std::string menu_filename = p.menu_filename;
+
+	if (!menu_filename.empty())
+	{
+		mMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
+		if (!mMenu)
+		{
+			llwarns << "Error loading menu_button menu" << llendl;
+		}
+	}
+}
+
+void LLMenuButton::toggleMenu()
+{
+    if(!mMenu)
+		return;
+
+	if (mMenu->getVisible() || mMenuVisibleLastFrame)
+	{
+		mMenu->setVisible(FALSE);
+	}
+	else
+	{
+	    LLRect rect = getRect();
+		//mMenu->needsArrange(); //so it recalculates the visible elements
+		LLMenuGL::showPopup(getParent(), mMenu, rect.mLeft, rect.mBottom);
+	}
+}
+
+
+BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
+{
+	if( KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key))
+	{
+		toggleMenu();
+		return TRUE;
+	}
+
+	if (mMenu && mMenu->getVisible() && key == KEY_ESCAPE && mask == MASK_NONE)
+	{
+		mMenu->setVisible(FALSE);
+		return TRUE;
+	}
+	
+	return FALSE;
+}
+
+BOOL LLMenuButton::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	if (hasTabStop() && !getIsChrome())
+	{
+		setFocus(TRUE);
+	}
+
+	toggleMenu();
+	
+	if (getSoundFlags() & MOUSE_DOWN)
+	{
+		make_ui_sound("UISndClick");
+	}
+
+	return TRUE;
+}
+
+void LLMenuButton::draw()
+{
+	//we save this off so next frame when we try to close it by 
+	//button click, and it hides menus before we get to it, we know
+	mMenuVisibleLastFrame = mMenu && mMenu->getVisible();
+	
+	if (mMenuVisibleLastFrame)
+	{
+		setForcePressedState(TRUE);
+	}
+
+	LLButton::draw();
+
+	setForcePressedState(FALSE);
+}
+

File indra/llui/llmenubutton.h

+/** 
+ * @file llbutton.h
+ * @brief Header for buttons
+ *
+ * $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$
+ */
+
+#ifndef LL_LLMENUBUTTON_H
+#define LL_LLMENUBUTTON_H
+
+#include "llbutton.h"
+
+class LLMenuGL;
+
+class LLMenuButton
+: public LLButton
+{
+public:
+	struct Params 
+	:	public LLInitParam::Block<Params, LLButton::Params>
+	{
+		// filename for it's toggleable menu
+		Optional<std::string>	menu_filename;
+	
+		Params();
+	};	
+	
+	void toggleMenu();
+	/*virtual*/ void draw();
+	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask );
+
+protected:
+	friend class LLUICtrlFactory;
+	LLMenuButton(const Params&);
+
+private:
+	LLMenuGL*	mMenu;
+	bool mMenuVisibleLastFrame;
+};
+
+
+#endif  // LL_LLMENUBUTTON_H

File indra/llui/llmenugl.cpp

 
 void LLMenuItemCallGL::initFromParams(const Params& p)
 {
+	if (p.on_visible.isProvided())
+	{
+		initVisibleCallback(p.on_visible, mVisibleSignal);
+	}
 	if (p.on_enable.isProvided())
 	{
 		initEnableCallback(p.on_enable, mEnableSignal);
 	}
 }
 
+void LLMenuItemCallGL::updateVisible( void )
+{
+	if (mVisibleSignal.num_slots() > 0)
+	{
+		bool visible = mVisibleSignal(this, LLSD());
+		setVisible(visible);
+	}
+}
+
 void LLMenuItemCallGL::buildDrawLabel( void )
 {
 	updateEnabled();
+	updateVisible();
 	LLMenuItemGL::buildDrawLabel();
 }
 
 			rect.translate(0, TEAROFF_SEPARATOR_HEIGHT_PIXELS);
 		}
 		branch->setRect( rect );
-		S32 x = 0;
-		S32 y = 0;
-		branch->localPointToOtherView( 0, 0, &x, &y, branch->getParent() ); 
-		S32 delta_x = 0;
-		S32 delta_y = 0;
-		if( y < menu_region_rect.mBottom )
-		{
-			delta_y = menu_region_rect.mBottom - y;
-		}
-
-		S32 menu_region_width = menu_region_rect.getWidth();
-		if( x - menu_region_rect.mLeft > menu_region_width - rect.getWidth() )
-		{
-			// move sub-menu over to left side
-			delta_x = llmax(-x, (-1 * (rect.getWidth() + getRect().getWidth())));
-		}
-		branch->translate( delta_x, delta_y );
+		branch->translateIntoRectWithExclusion( menu_region_rect, getMenu()->getRect(), FALSE );
 		branch->setVisible( TRUE );
 		branch->getParent()->sendChildToFront(branch);
 
 			item_list_t::iterator item_iter;
 			for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
 			{
+				// do first so LLMenuGLItemCall can call on_visible to determine if visible
+				(*item_iter)->buildDrawLabel();
+
 				if ((*item_iter)->getVisible())
 				{
 					if (!getTornOff() 
 
 			for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
 			{
+				// do first so LLMenuGLItemCall can call on_visible to determine if visible
+				(*item_iter)->buildDrawLabel();
+		
 				if ((*item_iter)->getVisible())
 				{
 					if (!getTornOff() 
 
 		item_list_t::iterator item_iter;
 		for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
-		{
+		{		
 			if ((*item_iter)->getVisible())
 			{
 				if (mScrollable)
 					}
 				}
 				(*item_iter)->setRect( rect );
-				(*item_iter)->buildDrawLabel();
 			}
 		}
 	}
 // static
 void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 {
+	const S32 CURSOR_HEIGHT = 22;		// Approximate "normal" cursor size
+	const S32 CURSOR_WIDTH = 12;
+
 	// Save click point for detecting cursor moves before mouse-up.
 	// Must be in local coords to compare with mouseUp events.
 	// If the mouse doesn't move, the menu will stay open ala the Mac.
 	// See also LLContextMenu::show()
 	S32 mouse_x, mouse_y;
+
+	// Resetting scrolling position
+	if (menu->isScrollable())
+	{
+		menu->mFirstVisibleItem = NULL;
+	}
+
+	menu->setVisible( TRUE );
+
+	// Fix menu rect if needed.
+	menu->needsArrange();
+	menu->arrangeAndClear();
+
 	LLUI::getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y);
 	LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y);
 
 
 	const S32 HPAD = 2;
 	LLRect rect = menu->getRect();
-	//LLView* cur_view = spawning_view;
 	S32 left = x + HPAD;
 	S32 top = y;
 	spawning_view->localPointToOtherView(left, top, &left, &top, menu->getParent());
 							rect.getWidth(), rect.getHeight() );
 	menu->setRect( rect );
 
-	// Resetting scrolling position
-	if (menu->isScrollable())
-	{
-		menu->mFirstVisibleItem = NULL;
-		menu->needsArrange();
-	}
-	menu->arrangeAndClear(); // Fix menu rect if needed.
-	rect = menu->getRect();
 
 	// Adjust context menu to fit onscreen
-	S32 bottom;
-	left = rect.mLeft;
-	bottom = rect.mBottom;
-	S32 delta_x = 0;
-	S32 delta_y = 0;
-	if( bottom < menu_region_rect.mBottom )
-	{
-		// At this point, we need to move the context menu to the
-		// other side of the mouse.
-		delta_y = (rect.getHeight() + 2 * HPAD);
-	}
-
-	if( left > menu_region_rect.mRight - rect.getWidth() )
-	{
-		// At this point, we need to move the context menu to the
-		// other side of the mouse.
-		delta_x = -(rect.getWidth() + 2 * HPAD);
-	}
-	menu->translate( delta_x, delta_y );
-	menu->setVisible( TRUE );
+	LLRect mouse_rect;
+	const S32 MOUSE_CURSOR_PADDING = 5;
+	mouse_rect.setLeftTopAndSize(mouse_x - MOUSE_CURSOR_PADDING, 
+		mouse_y + MOUSE_CURSOR_PADDING, 
+		CURSOR_WIDTH + MOUSE_CURSOR_PADDING * 2, 
+		CURSOR_HEIGHT + MOUSE_CURSOR_PADDING * 2);
+	menu->translateIntoRectWithExclusion( menu_region_rect, mouse_rect, FALSE );
 	menu->getParent()->sendChildToFront(menu);
+
+
+
 }
 
 ///============================================================================

File indra/llui/llmenugl.h

 	{
 		Optional<EnableCallbackParam > on_enable;
 		Optional<CommitCallbackParam > on_click;
+		Optional<VisibleCallbackParam > on_visible;
 		Params()
 			: on_enable("on_enable"),
-			  on_click("on_click")
+			  on_click("on_click"),
+			  on_visible("on_visible")
 		{}
 	};
 protected:
 	LLMenuItemCallGL(const Params&);
 	friend class LLUICtrlFactory;
 	void updateEnabled( void );
+	void updateVisible( void );
 
 public:
 	void initFromParams(const Params& p);
 	{
 		return mEnableSignal.connect(cb);
 	}
-
+	
+	boost::signals2::connection setVisibleCallback( const visible_signal_t::slot_type& cb )
+	{
+		return mVisibleSignal.connect(cb);
+	}
 	
 private:
 	enable_signal_t mEnableSignal;
+	visible_signal_t mVisibleSignal;
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

File indra/llui/llmultisliderctrl.cpp

 		LLTextBox::Params params;
 		params.name("MultiSliderCtrl Label");
 		params.rect(label_rect);
-		params.text(p.label);
+		params.initial_value(p.label());
 		params.font(p.font);
 		mLabelBox = LLUICtrlFactory::create<LLTextBox> (params);
 		addChild(mLabelBox);

File indra/llui/llpanel.cpp

 	}
 }
 
-void LLPanel::childSetWrappedText(const std::string& id, const std::string& text, bool visible)
-{
-	LLTextBox* child = findChild<LLTextBox>(id);
-	if (child)
-	{
-		child->setVisible(visible);
-		child->setWrappedText(text);
-	}
-}
 
 void LLPanel::childSetAction(const std::string& id, boost::function<void(void*)> function, void* value)
 {

File indra/llui/llpanel.h

 	void childShowTab(const std::string& id, const std::string& tabname, bool visible = true);
 	LLPanel *childGetVisibleTab(const std::string& id) const;
 
-	// LLTextBox
-	void childSetWrappedText(const std::string& id, const std::string& text, bool visible = true);
-
 	// LLTextBox/LLTextEditor/LLLineEditor
 	void childSetText(const std::string& id, const LLStringExplicit& text) { childSetValue(id, LLSD(text)); }
 
 	LLCallbackMap::map_t mFactoryMap;
 	CommitCallbackRegistry::ScopedRegistrar mCommitCallbackRegistrar;
 	EnableCallbackRegistry::ScopedRegistrar mEnableCallbackRegistrar;
-	
+	VisibleCallbackRegistry::ScopedRegistrar mVisibleCallbackRegistrar;
+
 	commit_signal_t mVisibleSignal;		// Called when visibility changes, passes new visibility as LLSD()
 
 	std::string		mHelpTopic;         // the name of this panel's help topic to display in the Help Viewer

File indra/llui/llradiogroup.cpp

 	name = "radio_group";
 	mouse_opaque = true;
 	follows.flags = FOLLOWS_LEFT | FOLLOWS_TOP;
+	// radio items are not tabbable until they are selected
+	tab_stop = false;
 }
 
 LLRadioGroup::LLRadioGroup(const LLRadioGroup::Params& p)

File indra/llui/llradiogroup.h

 {
 public:
 	struct Params : public LLInitParam::Block<Params, LLCheckBoxCtrl::Params>
-	{
-		Ignored		length;
-		Ignored		type;
-
-		Params() 
-		:	length("length"),
-			type("type")
-		{
-			// radio items are not tabbable until they are selected
-			tab_stop = false;
-		}
-	};
+	{};
 
 	/*virtual*/ ~LLRadioCtrl();
 	/*virtual*/ void setValue(const LLSD& value);

File indra/llui/llscrollbar.cpp

 		mCurGlowStrength(0.f),
 		mTrackColor( p.track_color() ),
 		mThumbColor ( p.thumb_color() ),
-		mOnScrollEndCallback( NULL ),
-		mOnScrollEndData( NULL ),
 		mThumbImageV(p.thumb_image_vertical),
 		mThumbImageH(p.thumb_image_horizontal),
 		mTrackImageV(p.track_image_vertical),
 		mThumbRect.mRight = thumb_start + thumb_length;
 		mThumbRect.mBottom = 0;
 	}
-	
-	if (mOnScrollEndCallback && mOnScrollEndData && (mDocPos == getDocPosMax()))
-	{
-		mOnScrollEndCallback(mOnScrollEndData);
-	}
 }
 
 BOOL LLScrollbar::handleMouseDown(S32 x, S32 y, MASK mask)
 		}
 	}
 
-	BOOL was_scrolled_to_bottom = (getDocPos() == getDocPosMax());
-	if (mOnScrollEndCallback && was_scrolled_to_bottom)
-	{
-		mOnScrollEndCallback(mOnScrollEndData);
-	}
-
 	// Draw children
 	LLView::draw();
 } // end draw

File indra/llui/llscrollbar.h

 	LLUIImagePtr		mTrackImageH;
 
 	S32					mThickness;
-
-	void			(*mOnScrollEndCallback)(void*);
-	void			*mOnScrollEndData;
 };
 
 

File indra/llui/llscrollcontainer.cpp

 :	is_opaque("opaque"),
 	bg_color("color"),
 	border_visible("border_visible"),
+	hide_scrollbar("hide_scrollbar"),
 	min_auto_scroll_rate("min_auto_scroll_rate", 100),
 	max_auto_scroll_rate("max_auto_scroll_rate", 1000),
 	reserve_scroll_corner("reserve_scroll_corner", false)
 	mAutoScrollRate( 0.f ),
 	mBackgroundColor(p.bg_color()),
 	mIsOpaque(p.is_opaque),
+	mHideScrollbar(p.hide_scrollbar),
 	mReserveScrollCorner(p.reserve_scroll_corner),
 	mMinAutoScrollRate(p.min_auto_scroll_rate),
 	mMaxAutoScrollRate(p.max_auto_scroll_rate),
 	S32 doc_width = doc_rect.getWidth();
 	S32 doc_height = doc_rect.getHeight();
 
-	*visible_width = getRect().getWidth() - 2 * mBorder->getBorderWidth();
-	*visible_height = getRect().getHeight() - 2 * mBorder->getBorderWidth();
+	S32 border_width = (mBorder->getVisible() ? 2 * mBorder->getBorderWidth() : 0);
+	*visible_width = getRect().getWidth() - border_width;
+	*visible_height = getRect().getHeight() - border_width;
 	
 	*show_v_scrollbar = FALSE;
-	if( *visible_height < doc_height )
+	*show_h_scrollbar = FALSE;
+
+	if (!mHideScrollbar)
 	{
-		*show_v_scrollbar = TRUE;
-		*visible_width -= scrollbar_size;
-	}
-
-	*show_h_scrollbar = FALSE;
-	if( *visible_width < doc_width )
-	{
-		*show_h_scrollbar = TRUE;
-		*visible_height -= scrollbar_size;
-
-		// Must retest now that visible_height has changed
-		if( !*show_v_scrollbar && (*visible_height < doc_height) )
+		if( *visible_height < doc_height )
 		{
 			*show_v_scrollbar = TRUE;
 			*visible_width -= scrollbar_size;
 		}
+
+		if( *visible_width < doc_width )
+		{
+			*show_h_scrollbar = TRUE;
+			*visible_height -= scrollbar_size;
+
+			// Must retest now that visible_height has changed
+			if( !*show_v_scrollbar && (*visible_height < doc_height) )
+			{
+				*show_v_scrollbar = TRUE;
+				*visible_width -= scrollbar_size;
+			}
+		}
 	}
 }
 	
 			sDepth--;
 		}
 	}
-
-	if (sDebugRects)
-	{
-		drawDebugRect();
-	}
-
-	//// *HACK: also draw debug rectangles around currently-being-edited LLView, and any elements that are being highlighted by GUI preview code (see LLFloaterUIPreview)
-	//std::set<LLView*>::iterator iter = std::find(sPreviewHighlightedElements.begin(), sPreviewHighlightedElements.end(), this);
-	//if ((sEditingUI && this == sEditingUIView) || (iter != sPreviewHighlightedElements.end() && sDrawPreviewHighlights))
-	//{
-	//	drawDebugRect();
-	//}
-
 } // end draw
 
 bool LLScrollContainer::addChild(LLView* view, S32 tab_group)
 	BOOL show_h_scrollbar = FALSE;
 	BOOL show_v_scrollbar = FALSE;
 	calcVisibleSize( &visible_width, &visible_height, &show_h_scrollbar, &show_v_scrollbar );
-	S32 border_width = mBorder->getBorderWidth();
+	S32 border_width = mBorder->getVisible() ? mBorder->getBorderWidth() : 0;
 	scroller_view_rect.setOriginAndSize(border_width, 
 										show_h_scrollbar ? mScrollbar[HORIZONTAL]->getRect().mTop : border_width, 
 										visible_width, 

File indra/llui/llscrollcontainer.h

 	{
 		Optional<bool>		is_opaque,
 							reserve_scroll_corner,
-							border_visible;
+							border_visible,
+							hide_scrollbar;
 		Optional<F32>		min_auto_scroll_rate,
 							max_auto_scroll_rate;
 		Optional<LLUIColor>	bg_color;
 	F32			mAutoScrollRate;
 	F32			mMinAutoScrollRate;
 	F32			mMaxAutoScrollRate;
+	bool		mHideScrollbar;
 };
 
 

File indra/llui/llscrolllistcell.cpp

 	return TRUE;
 }
 
+BOOL LLScrollListText::needsToolTip() const
+{
+	// show tooltips for truncated text
+	return mFont->getWidth(mText.getString()) > getWidth();
+}
+
+
 //virtual 
 BOOL LLScrollListText::getVisible() const
 {

File indra/llui/llscrolllistcell.h

 
 	LLScrollListCell(const LLScrollListCell::Params&);
 	virtual ~LLScrollListCell() {};
-	virtual void			draw(const LLColor4& color, const LLColor4& highlight_color) const = 0;		// truncate to given width, if possible
+
+	virtual void			draw(const LLColor4& color, const LLColor4& highlight_color) const {};		// truncate to given width, if possible
 	virtual S32				getWidth() const {return mWidth;}
 	virtual S32				getContentWidth() const { return 0; }
-	virtual S32				getHeight() const = 0;
+	virtual S32				getHeight() const { return 0; }
 	virtual const LLSD		getValue() const;
 	virtual void			setValue(const LLSD& value) { }
 	virtual BOOL			getVisible() const { return TRUE; }
 	virtual void			setWidth(S32 width) { mWidth = width; }
 	virtual void			highlightText(S32 offset, S32 num_chars) {}
-	virtual BOOL			isText() const = 0;
+	virtual BOOL			isText() const { return FALSE; }
+	virtual BOOL			needsToolTip() const { return FALSE; }
 	virtual void			setColor(const LLColor4&) {}
 	virtual void			onCommit() {};
 
 	LLScrollListSpacer(const LLScrollListCell::Params& p) : LLScrollListCell(p) {}
 	/*virtual*/ ~LLScrollListSpacer() {};
 	/*virtual*/ void			draw(const LLColor4& color, const LLColor4& highlight_color) const {}
-	/*virtual*/ S32				getHeight() const { return 0; }
-	/*virtual*/ BOOL			isText() const { return FALSE; }
 };
 
 /*
 
 	/*virtual*/ void	setColor(const LLColor4&);
 	/*virtual*/ BOOL	isText() const;
+	/*virtual*/ BOOL	needsToolTip() const;
 
 	void			setText(const LLStringExplicit& text);
 	void			setFontStyle(const U8 font_style);
 	/*virtual*/ S32		getHeight() const;
 	/*virtual*/ const LLSD		getValue() const;
 	/*virtual*/ void	setColor(const LLColor4&);
-	/*virtual*/ BOOL	isText()const { return FALSE; }
 	/*virtual*/ void	setValue(const LLSD& value);
 
 private:
 	/*virtual*/ void	setEnabled(BOOL enable);
 
 	LLCheckBoxCtrl*	getCheckBox()				{ return mCheckBox; }
-	/*virtual*/ BOOL	isText() const				{ return FALSE; }
 
 private:
 	LLCheckBoxCtrl* mCheckBox;

File indra/llui/llscrolllistctrl.cpp

 	sbparams.orientation(LLScrollbar::VERTICAL);
 	sbparams.doc_size(getItemCount());
 	sbparams.doc_pos(mScrollLines);
-	sbparams.page_size( mPageLines ? mPageLines : getItemCount() );
+	sbparams.page_size( getLinesPerPage() );
 	sbparams.change_callback(boost::bind(&LLScrollListCtrl::onScrollChange, this, _1, _2));
 	sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
 	sbparams.visible(false);
 	getChildView("comment_text")->setShape(mItemListRect);
 
 	// how many lines of content in a single "page"
-	S32 page_lines =  mLineHeight? mItemListRect.getHeight() / mLineHeight : getItemCount();
-	//if mPageLines is NOT provided display all item
-	if(mPageLines)
-		page_lines = mPageLines;
+	S32 page_lines =  getLinesPerPage();
 
 	BOOL scrollbar_visible = mLineHeight * getItemCount() > mItemListRect.getHeight();
 	if (scrollbar_visible)
 	S32 y = mItemListRect.mTop - mLineHeight;
 
 	// allow for partial line at bottom
-	S32 num_page_lines = (mPageLines)? mPageLines : getItemCount() + 1;
+	S32 num_page_lines = getLinesPerPage();
 
 	LLRect item_rect;
 
 	return handled;
 }
 
-BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect_screen)
+// *NOTE: Requires a valid row_index and column_index
+LLRect LLScrollListCtrl::getCellRect(S32 row_index, S32 column_index)
+{
+	LLRect cell_rect;
+	S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft;
+	S32 rect_bottom = getRowOffsetFromIndex(row_index);
+	LLScrollListColumn* columnp = getColumn(column_index);
+	cell_rect.setOriginAndSize(rect_left, rect_bottom,
+		rect_left + columnp->getWidth(), mLineHeight);
+	return cell_rect;
+}
+
+BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
 {
 	S32 column_index = getColumnIndexFromOffset(x);
 	LLScrollListColumn* columnp = getColumn(column_index);
 	{
 		LLScrollListCell* hit_cell = hit_item->getColumn(column_index);
 		if (!hit_cell) return FALSE;
-		//S32 cell_required_width = hit_cell->getContentWidth();
 		if (hit_cell 
-			&& hit_cell->isText())
+			&& hit_cell->isText()
+			&& hit_cell->needsToolTip())
 		{
-			S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft;
-			S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item));
-			LLRect cell_rect;
-			cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight);
+			S32 row_index = getItemIndex(hit_item);
+			LLRect cell_rect = getCellRect(row_index, column_index);
 			// Convert rect local to screen coordinates
 			LLRect sticky_rect;
 			localRectToScreen(cell_rect, &sticky_rect);
-			LLToolTipMgr::instance().show(LLToolTipParams()
-				.message(hit_cell->getValue().asString())
-				.sticky_rect(sticky_rect));		
+
+			// display tooltip exactly over original cell, in same font
+			LLToolTipMgr::instance().show(LLToolTip::Params()
+										.message(hit_cell->getValue().asString())
+										.font(LLFontGL::getFontSansSerifSmall())
+										.pos(LLCoordGL(sticky_rect.mLeft - 5, sticky_rect.mTop + 4))
+										.delay_time(0.2f)
+										.sticky_rect(sticky_rect));		
 		}
 		handled = TRUE;
 	}
 	LLScrollColumnHeader* headerp = columnp->mHeader;
 	if (headerp && !handled)
 	{
-		handled = headerp->handleToolTip(x, y, msg, sticky_rect_screen);
+		handled = headerp->handleToolTip(x, y, mask);
 	}
 
 	return handled;
 		mLineHeight );
 
 	// allow for partial line at bottom
-	S32 num_page_lines = (mPageLines)? mPageLines : getItemCount() + 1;
+	S32 num_page_lines = getLinesPerPage();
 
 	S32 line = 0;
 	item_list::iterator iter;
 	}
 }
 
+S32	LLScrollListCtrl::getLinesPerPage()
+{
+	//if mPageLines is NOT provided display all item
+	if(mPageLines)
+	{
+		return mPageLines;
+	}
+	else
+	{
+		return mLineHeight ? mItemListRect.getHeight() / mLineHeight : getItemCount();
+	}
+}
+
+
 // Called by scrollbar
 void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar )
 {
 	}
 
 	S32 lowest = mScrollLines;
-	S32 page_lines = (mPageLines)? mPageLines : getItemCount();
+	S32 page_lines = getLinesPerPage();
 	S32 highest = mScrollLines + page_lines;
 
 	if (index < lowest)

File indra/llui/llscrolllistctrl.h

 	/*virtual*/ BOOL	handleKeyHere(KEY key, MASK mask);
 	/*virtual*/ BOOL	handleUnicodeCharHere(llwchar uni_char);
 	/*virtual*/ BOOL	handleScrollWheel(S32 x, S32 y, S32 clicks);
-	/*virtual*/ BOOL	handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect);
+	/*virtual*/ BOOL	handleToolTip(S32 x, S32 y, MASK mask);
 	/*virtual*/ void	setEnabled(BOOL enabled);
 	/*virtual*/ void	setFocus( BOOL b );
 	/*virtual*/ void	onFocusReceived();
 
 	LLRect			getItemListRect() { return mItemListRect; }
 
+	/// Returns rect, in local coords, of a given row/column
+	LLRect			getCellRect(S32 row_index, S32 column_index);
+
 	// Used "internally" by the scroll bar.
 	void			onScrollChange( S32 new_pos, LLScrollbar* src );
 
 	void			deselectItem(LLScrollListItem* itemp);
 	void			commitIfChanged();
 	BOOL			setSort(S32 column, BOOL ascending);
+	S32				getLinesPerPage();
 
 	static void		showNameDetails(std::string id, bool is_group);
 	static void		copyNameToClipboard(std::string id, bool is_group);

File indra/llui/llscrolllistitem.cpp

 #include "llscrolllistitem.h"
 
 #include "llrect.h"
-#include "llresmgr.h"		// LLFONT_SANSSERIF_SMALL
 #include "llui.h"
 
 

File indra/llui/llscrolllistitem.h

 #ifndef LLSCROLLLISTITEM_H
 #define LLSCROLLLISTITEM_H
 
-#include "llfontgl.h"		// LLFontGL::HAlign
 #include "llpointer.h"		// LLPointer<>
 #include "llsd.h"
-#include "lluistring.h"
 #include "v4color.h"
 #include "llinitparam.h"
 #include "llscrolllistcell.h"

File indra/llui/llsliderctrl.cpp

 		LLTextBox::Params params(p.slider_label);
 		params.rect.setIfNotProvided(label_rect);
 		params.font.setIfNotProvided(p.font);
-		params.text(p.label);
+		params.initial_value(p.label());
 		mLabelBox = LLUICtrlFactory::create<LLTextBox> (params);
 		addChild(mLabelBox);
 	}

File indra/llui/llspinctrl.cpp

 		LLTextBox::Params params;
 		params.name("SpinCtrl Label");
 		params.rect(label_rect);
-		params.text(p.label);
+		params.initial_value(p.label());
 		if (p.font.isProvided())
 		{
 			params.font(p.font);

File indra/llui/llstatview.cpp

 
 static StatViewRegistry::Register<LLStatBar> r1("stat_bar");
 static StatViewRegistry::Register<LLStatView> r2("stat_view");
+// stat_view can be a child of panels/etc.
+static LLDefaultChildRegistry::Register<LLStatView> r3("stat_view");
 
 

File indra/llui/llstyle.cpp

 
 LLStyle::Params::Params()
 :	visible("visible", true),
-	drop_shadow("drop_shadow", false),
+	drop_shadow("drop_shadow", LLFontGL::NO_SHADOW),
 	color("color", LLColor4::black),
 	font("font", LLFontGL::getFontMonospace()),
 	image("image"),

File indra/llui/llstyle.h

 public:
 	struct Params : public LLInitParam::Block<Params>
 	{
-		Optional<bool>				visible,
-									drop_shadow;
-		Optional<LLUIColor>			color;
-		Optional<const LLFontGL*>	font;
-		Optional<LLUIImage*>		image;
-		Optional<std::string>		link_href;
+		Optional<bool>					visible;
+		Optional<LLFontGL::ShadowType>	drop_shadow;
+		Optional<LLUIColor>				color;
+		Optional<const LLFontGL*>		font;
+		Optional<LLUIImage*>			image;
+		Optional<std::string>			link_href;
 		Params();
 	};
 	LLStyle(const Params& p = Params());
 	BOOL isVisible() const;
 	void setVisible(BOOL is_visible);
 
+	LLFontGL::ShadowType getShadowType() { return mDropShadow; }
+
 	void setFont(const LLFontGL* font);
 	const LLFontGL* getFont() const;
 
 	BOOL        mItalic;
 	BOOL        mBold;
 	BOOL        mUnderline;
-	BOOL		mDropShadow;
+	LLFontGL::ShadowType		mDropShadow;
 
 protected:
 	~LLStyle() { }

File indra/llui/lltabcontainer.cpp

 }
 
 // virtual
-BOOL LLTabContainer::handleToolTip( S32 x, S32 y, std::string& msg, LLRect& sticky_rect )
+BOOL LLTabContainer::handleToolTip( S32 x, S32 y, MASK mask)
 {
 	static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
-	BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect );
+	BOOL handled = LLPanel::handleToolTip( x, y, mask);
 	if (!handled && getTabCount() > 0) 
 	{
 		LLTabTuple* firsttuple = getTab(0);
 				tuple->mButton->setVisible( TRUE );
 				S32 local_x = x - tuple->mButton->getRect().mLeft;
 				S32 local_y = y - tuple->mButton->getRect().mBottom;
-				handled = tuple->mButton->handleToolTip( local_x, local_y, msg, sticky_rect );
+				handled = tuple->mButton->handleToolTip( local_x, local_y, mask);
 				if( handled )
 				{
 					break;
 		LLTextBox::Params params;
 		params.name(trimmed_label);
 		params.rect(btn_rect);
-		params.text(trimmed_label);
+		params.initial_value(trimmed_label);
 		params.font(font);
 		textbox = LLUICtrlFactory::create<LLTextBox> (params);
 		

File indra/llui/lltabcontainer.h

 	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
 	/*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask );
 	/*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask );
-	/*virtual*/ BOOL handleToolTip(S32 x, S32 y, std::string& msg, LLRect& sticky_rect );
+	/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
 	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,	BOOL drop,
 									   EDragAndDropType type, void* cargo_data,

File indra/llui/lltextbase.cpp

 #include "linden_common.h"
 
 #include "lltextbase.h"
+
+#include "lllocalcliprect.h"
+#include "llmenugl.h"
+#include "llscrollcontainer.h"
 #include "llstl.h"
-#include "llview.h"
-#include "llwindow.h"
-#include "llmenugl.h"
+#include "lltextparser.h"
 #include "lltooltip.h"
 #include "lluictrl.h"
 #include "llurlaction.h"
 #include "llurlregistry.h"
-
+#include "llview.h"
+#include "llwindow.h"
 #include <boost/bind.hpp>
 
-// global state for all text fields
-LLUIColor LLTextBase::mLinkColor = LLColor4::blue;
+const F32	CURSOR_FLASH_DELAY = 1.0f;  // in seconds
+const S32	CURSOR_THICKNESS = 2;
+
+LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num) 
+:	mDocIndexStart(index_start), 
+	mDocIndexEnd(index_end),
+	mRect(rect),
+	mLineNum(line_num)
+{}
 
 bool LLTextBase::compare_segment_end::operator()(const LLTextSegmentPtr& a, const LLTextSegmentPtr& b) const
 {
 	return a->getEnd() < b->getEnd();
 }
 
+
+// helper functors
+struct LLTextBase::compare_bottom
+{
+	bool operator()(const S32& a, const LLTextBase::line_info& b) const
+	{
+		return a > b.mRect.mBottom; // bottom of a is higher than bottom of b
+	}
+
+	bool operator()(const LLTextBase::line_info& a, const S32& b) const
+	{
+		return a.mRect.mBottom > b; // bottom of a is higher than bottom of b
+	}
+
+	bool operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const
+	{
+		return a.mRect.mBottom > b.mRect.mBottom; // bottom of a is higher than bottom of b
+	}
+
+};
+
+// helper functors
+struct LLTextBase::compare_top
+{
+	bool operator()(const S32& a, const LLTextBase::line_info& b) const
+	{
+		return a > b.mRect.mTop; // top of a is higher than top of b
+	}
+
+	bool operator()(const LLTextBase::line_info& a, const S32& b) const
+	{
+		return a.mRect.mTop > b; // top of a is higher than top of b
+	}
+
+	bool operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const
+	{
+		return a.mRect.mTop > b.mRect.mTop; // top of a is higher than top of b
+	}
+};
+
+struct LLTextBase::line_end_compare
+{
+	bool operator()(const S32& pos, const LLTextBase::line_info& info) const
+	{
+		return (pos < info.mDocIndexEnd);
+	}
+
+	bool operator()(const LLTextBase::line_info& info, const S32& pos) const
+	{
+		return (info.mDocIndexEnd < pos);
+	}
+
+	bool operator()(const LLTextBase::line_info& a, const LLTextBase::line_info& b) const
+	{
+		return (a.mDocIndexEnd < b.mDocIndexEnd);
+	}
+
+};
+
+//////////////////////////////////////////////////////////////////////////
+//
+// LLTextBase::DocumentPanel
+//
+
+
+LLTextBase::DocumentPanel::DocumentPanel(const Params& p)
+: LLPanel(p)
+{}
+
+
+//////////////////////////////////////////////////////////////////////////
+//
+// LLTextBase
+//
+
+// register LLTextBase::Params under name "textbase"
+static LLWidgetNameRegistry::StaticRegistrar sRegisterTextBaseParams(&typeid(LLTextBase::Params), "textbase");
+