diff options
Diffstat (limited to 'indra/llui')
| -rw-r--r-- | indra/llui/llbutton.cpp | 3 | ||||
| -rw-r--r-- | indra/llui/llfolderview.cpp | 101 | ||||
| -rw-r--r-- | indra/llui/llfolderview.h | 19 | ||||
| -rw-r--r-- | indra/llui/llfolderviewitem.cpp | 153 | ||||
| -rw-r--r-- | indra/llui/llfolderviewitem.h | 15 | ||||
| -rw-r--r-- | indra/llui/llfolderviewmodel.cpp | 4 | ||||
| -rw-r--r-- | indra/llui/llfolderviewmodel.h | 8 | ||||
| -rw-r--r-- | indra/llui/lliconctrl.h | 4 | ||||
| -rw-r--r-- | indra/llui/lllayoutstack.cpp | 17 | ||||
| -rw-r--r-- | indra/llui/lllayoutstack.h | 4 | ||||
| -rw-r--r-- | indra/llui/llmenugl.cpp | 17 | ||||
| -rw-r--r-- | indra/llui/llmenugl.h | 9 | ||||
| -rw-r--r-- | indra/llui/llscrollbar.cpp | 11 | ||||
| -rw-r--r-- | indra/llui/llscrollbar.h | 4 | ||||
| -rw-r--r-- | indra/llui/llscrollcontainer.cpp | 11 | ||||
| -rw-r--r-- | indra/llui/llscrollcontainer.h | 6 | ||||
| -rw-r--r-- | indra/llui/lltabcontainer.cpp | 16 | ||||
| -rw-r--r-- | indra/llui/lltabcontainer.h | 1 | ||||
| -rw-r--r-- | indra/llui/lltooltip.cpp | 36 | ||||
| -rw-r--r-- | indra/llui/lltooltip.h | 12 | ||||
| -rw-r--r-- | indra/llui/lluictrl.cpp | 9 | ||||
| -rw-r--r-- | indra/llui/lluictrl.h | 1 | ||||
| -rw-r--r-- | indra/llui/llview.cpp | 29 | ||||
| -rw-r--r-- | indra/llui/llview.h | 1 | 
24 files changed, 395 insertions, 96 deletions
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index 061c24db50..ceceb90f0a 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -204,7 +204,8 @@ LLButton::LLButton(const LLButton::Params& p)  	}  	// Hack to make sure there is space for at least one character -	if (getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(std::string(" "))) +	if (getRect().mRight >= 0 && getRect().getWidth() > 0 && +		getRect().getWidth() - (mRightHPad + mLeftHPad) < mGLFont->getWidth(std::string(" ")))  	{  		// Use old defaults  		mLeftHPad = llbutton_orig_h_pad; diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp index ed49c0dcfd..bbbb4afb54 100644 --- a/indra/llui/llfolderview.cpp +++ b/indra/llui/llfolderview.cpp @@ -189,7 +189,9 @@ LLFolderView::LLFolderView(const Params& p)  	mStatusTextBox(NULL),  	mShowItemLinkOverlays(p.show_item_link_overlays),  	mViewModel(p.view_model), -    mGroupedItemModel(p.grouped_item_model) +    mGroupedItemModel(p.grouped_item_model), +    mForceArrange(false), +    mSingleFolderMode(false)  {      LLPanel* panel = p.parent_panel;      mParentPanel = panel->getHandle(); @@ -609,6 +611,7 @@ void LLFolderView::clearSelection()  	}  	mSelectedItems.clear(); +    mNeedsScroll = false;  }  std::set<LLFolderViewItem*> LLFolderView::getSelectionList() const @@ -665,7 +668,7 @@ void LLFolderView::draw()  	}  	else if (mShowEmptyMessage)  	{ -		mStatusTextBox->setValue(getFolderViewModel()->getStatusText()); +		mStatusTextBox->setValue(getFolderViewModel()->getStatusText(mItems.empty() && mFolders.empty()));  		mStatusTextBox->setVisible( TRUE );  		// firstly reshape message textbox with current size. This is necessary to @@ -693,12 +696,16 @@ void LLFolderView::draw()  		}  	} -	if (mRenameItem && mRenamer && mRenamer->getVisible() && !getVisibleRect().overlaps(mRenamer->getRect())) -	{ -		// renamer is not connected to the item we are renaming in any form so manage it manually -		// TODO: consider stopping on any scroll action instead of when out of visible area -		finishRenamingItem(); -	} +    if (mRenameItem +        && mRenamer +        && mRenamer->getVisible() +        && !getVisibleRect().overlaps(mRenamer->getRect())) +    { +        // renamer is not connected to the item we are renaming in any form so manage it manually +        // TODO: consider stopping on any scroll action instead of when out of visible area +        LL_DEBUGS("Inventory") << "Renamer out of bounds, hiding" << LL_ENDL; +        finishRenamingItem(); +    }  	// skip over LLFolderViewFolder::draw since we don't want the folder icon, label,   	// and arrow for the root folder @@ -832,9 +839,12 @@ void LLFolderView::autoOpenItem( LLFolderViewFolder* item )  	mAutoOpenItems.push(item);  	item->setOpen(TRUE); +    if(!item->isSingleFolderMode()) +    {  	LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());  	LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);  	scrollToShowItem(item, constraint_rect); +    }  }  void LLFolderView::closeAutoOpenedFolders() @@ -1038,6 +1048,8 @@ void LLFolderView::paste()  // public rename functionality - can only start the process  void LLFolderView::startRenamingSelectedItem( void )  { +    LL_DEBUGS("Inventory") << "Starting inventory renamer" << LL_ENDL; +  	// make sure selection is visible  	scrollToShowSelection(); @@ -1273,6 +1285,11 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )  		if(mSelectedItems.size())  		{  			LLFolderViewItem* last_selected = getCurSelectedItem(); +            if(last_selected && last_selected->isSingleFolderMode()) +            { +                handled = FALSE; +                break; +            }  			LLFolderViewItem* parent_folder = last_selected->getParentFolder();  			if (!last_selected->isOpen() && parent_folder && parent_folder->getParentFolder())  			{ @@ -1458,9 +1475,19 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )  			mCallbackRegistrar->popScope();  		}  	} + +    BOOL item_clicked = FALSE; +    for (selected_items_t::iterator item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it) +    { +        item_clicked |= (*item_it)->getRect().pointInRect(x, y); +    } +    if(!item_clicked && mSingleFolderMode) +    { +        clearSelection(); +    }  	bool hide_folder_menu = mSuppressFolderMenu && isFolderSelected(); -	if (menu && (handled -		&& ( count > 0 && (hasVisibleChildren()) )) && // show menu only if selected items are visible +	if (menu && (mSingleFolderMode || (handled +		&& ( count > 0 && (hasVisibleChildren()) ))) && // show menu only if selected items are visible  		!hide_folder_menu)  	{  		if (mCallbackRegistrar) @@ -1532,6 +1559,22 @@ BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )  	return LLView::handleHover( x, y, mask );  } +LLFolderViewItem* LLFolderView::getHoveredItem() const +{ +	return dynamic_cast<LLFolderViewItem*>(mHoveredItem.get()); +} + +void LLFolderView::setHoveredItem(LLFolderViewItem* itemp) +{ +	if (mHoveredItem.get() != itemp) +	{ +		if (itemp) +			mHoveredItem = itemp->getHandle(); +		else +			mHoveredItem.markDead(); +	} +} +  BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,  									 EDragAndDropType cargo_type,  									 void* cargo_data,  @@ -1716,7 +1759,7 @@ void LLFolderView::update()  		mNeedsAutoSelect = FALSE;  	} -  BOOL is_visible = isInVisibleChain(); +  BOOL is_visible = isInVisibleChain() || mForceArrange;    //Puts folders/items in proper positions    // arrange() takes the model filter flag into account and call sort() if necessary (CHUI-849) @@ -1817,13 +1860,28 @@ void LLFolderView::update()          }  	} -	if (mSignalSelectCallback) -	{ -		//RN: we use keyboard focus as a proxy for user-explicit actions -		BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS); -		mSelectSignal(mSelectedItems, take_keyboard_focus); -	} -	mSignalSelectCallback = FALSE; +    if (mSelectedItems.size()) +    { +        LLFolderViewItem* item = mSelectedItems.back(); +        // If the goal is to show renamer, don't callback untill +        // item is visible or is no longer being scrolled to. +        // Otherwise renamer will be instantly closed +        // Todo: consider moving renamer out of selection callback +        if (!mNeedsAutoRename || !mNeedsScroll || item->getVisible()) +        { +            if (mSignalSelectCallback) +            { +                //RN: we use keyboard focus as a proxy for user-explicit actions +                BOOL take_keyboard_focus = (mSignalSelectCallback == SIGNAL_KEYBOARD_FOCUS); +                mSelectSignal(mSelectedItems, take_keyboard_focus); +            } +            mSignalSelectCallback = FALSE; +        } +    } +    else +    { +        mSignalSelectCallback = FALSE; +    }  }  void LLFolderView::dumpSelectionInformation() @@ -1886,6 +1944,11 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu)  		flags = multi_select_flag;  	} +    if(mSingleFolderMode && (mSelectedItems.size() == 0)) +    { +        buildContextMenu(*menu, flags); +    } +  	// This adds a check for restrictions based on the entire  	// selection set - for example, any one wearable may not push you  	// over the limit, but all wearables together still might. @@ -2042,7 +2105,7 @@ LLFolderViewItem* LLFolderView::getNextUnselectedItem()  	return new_selection;  } -S32 LLFolderView::getItemHeight() +S32 LLFolderView::getItemHeight() const  {  	if(!hasVisibleChildren())  { diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 7dfa04828a..6de366044c 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -127,6 +127,9 @@ public:  	bool getAllowMultiSelect() { return mAllowMultiSelect; }  	bool getAllowDrag() { return mAllowDrag; } +    void setSingleFolderMode(bool is_single_mode) { mSingleFolderMode = is_single_mode; } +    bool isSingleFolderMode() { return mSingleFolderMode; } +  	// Close all folders in the view  	void closeAllFolders();  	void openTopLevelFolders(); @@ -136,7 +139,7 @@ public:  	// Find width and height of this object and its children. Also  	// makes sure that this view and its children are the right size.  	virtual S32 arrange( S32* width, S32* height ); -	virtual S32 getItemHeight(); +	virtual S32 getItemHeight() const;  	void arrangeAll() { mArrangeGeneration++; }  	S32 getArrangeGeneration() { return mArrangeGeneration; } @@ -144,6 +147,10 @@ public:  	// applies filters to control visibility of items  	virtual void filter( LLFolderViewFilter& filter); +	void              clearHoveredItem() { setHoveredItem(nullptr); } +	LLFolderViewItem* getHoveredItem() const; +	void              setHoveredItem(LLFolderViewItem* itemp); +  	// Get the last selected item  	virtual LLFolderViewItem* getCurSelectedItem( void );      selected_items_t& getSelectedItems( void ); @@ -237,11 +244,15 @@ public:  	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }  	void setEnableRegistrar(LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* registrar) { mEnableRegistrar = registrar; } +    void setForceArrange(bool force) { mForceArrange = force; } +  	LLPanel* getParentPanel() { return mParentPanel.get(); }  	// DEBUG only  	void dumpSelectionInformation();  	virtual S32	notify(const LLSD& info) ; + +	void setShowEmptyMessage(bool show_msg) { mShowEmptyMessage = show_msg; }  	bool useLabelSuffix() { return mUseLabelSuffix; }  	virtual void updateMenu(); @@ -275,6 +286,7 @@ protected:  	LLHandle<LLView>					mPopupMenuHandle;  	std::string						mMenuFileName; +	LLHandle<LLView>				mHoveredItem;  	selected_items_t				mSelectedItems;  	bool							mKeyboardSelection,  									mAllowMultiSelect, @@ -291,7 +303,8 @@ protected:  									mShowItemLinkOverlays,  									mShowSelectionContext,  									mShowSingleSelection, -									mSuppressFolderMenu; +									mSuppressFolderMenu, +                                    mSingleFolderMode;  	// Renaming variables and methods  	LLFolderViewItem*				mRenameItem;  // The item currently being renamed @@ -330,6 +343,8 @@ protected:  	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* mCallbackRegistrar;  	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar* mEnableRegistrar; + +    bool mForceArrange;  public:  	static F32 sAutoOpenTime; diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp index ed0e705fd5..6ae150dca5 100644 --- a/indra/llui/llfolderviewitem.cpp +++ b/indra/llui/llfolderviewitem.cpp @@ -32,6 +32,7 @@  #include "llfolderview.h"  #include "llfolderviewmodel.h"  #include "llpanel.h" +#include "llcallbacklist.h"  #include "llcriticaldamp.h"  #include "llclipboard.h"  #include "llfocusmgr.h"		// gFocusMgr @@ -113,6 +114,8 @@ LLFolderViewItem::Params::Params()      icon_width("icon_width", 0),      text_pad("text_pad", 0),      text_pad_right("text_pad_right", 0), +    single_folder_mode("single_folder_mode", false), +    double_click_override("double_click_override", false),      arrow_size("arrow_size", 0),      max_folder_item_overlap("max_folder_item_overlap", 0)  { } @@ -151,7 +154,9 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)      mTextPad(p.text_pad),      mTextPadRight(p.text_pad_right),      mArrowSize(p.arrow_size), -    mMaxFolderItemOverlap(p.max_folder_item_overlap) +    mSingleFolderMode(p.single_folder_mode), +    mMaxFolderItemOverlap(p.max_folder_item_overlap), +    mDoubleClickOverride(p.double_click_override)  {  	if (!sColorSetInitialized)  	{ @@ -162,7 +167,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)  		sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);  		sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);  		sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE); -		sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE); +		sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);  		sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);  		sColorSetInitialized = true;  	} @@ -396,7 +401,7 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )              // it is purely visual, so it is fine to do at our laisure              refreshSuffix();          } -		mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight; +		mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(LLFontGL::NORMAL)->getWidth(mLabelSuffix) + mLabelPaddingRight;  		mLabelWidthDirty = false;  	} @@ -413,7 +418,7 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )  	return *height;  } -S32 LLFolderViewItem::getItemHeight() +S32 LLFolderViewItem::getItemHeight() const  {  	return mItemHeight;  } @@ -623,11 +628,14 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )  			getWindow()->setCursor(UI_CURSOR_NOLOCKED);  		} +		root->clearHoveredItem();  		return TRUE;  	}  	else  	{ -		getRoot()->setShowSelectionContext(FALSE); +		LLFolderView* pRoot = getRoot(); +		pRoot->setHoveredItem(this); +		pRoot->setShowSelectionContext(FALSE);  		getWindow()->setCursor(UI_CURSOR_ARROW);  		// let parent handle this then...  		return FALSE; @@ -682,6 +690,13 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )  void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)  {  	mIsMouseOverTitle = false; + +	// NOTE: LLViewerWindow::updateUI() calls "enter" before "leave"; if the mouse moved to another item, we can't just outright clear it +	LLFolderView* pRoot = getRoot(); +	if (this == pRoot->getHoveredItem()) +	{ +		pRoot->clearHoveredItem(); +	}  }  BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, @@ -888,7 +903,10 @@ void LLFolderViewItem::draw()      getViewModelItem()->update(); -    drawOpenFolderArrow(default_params, sFgColor); +    if(!mSingleFolderMode) +    { +        drawOpenFolderArrow(default_params, sFgColor); +    }      drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor); @@ -924,16 +942,43 @@ void LLFolderViewItem::draw()  	F32 text_left = (F32)getLabelXPos();  	std::string combined_string = mLabel + mLabelSuffix; +    const LLFontGL* suffix_font = getLabelFontForStyle(LLFontGL::NORMAL); +    S32 filter_offset = mViewModelItem->getFilterStringOffset();  	if (filter_string_length > 0)  	{ -		S32 left = ll_round(text_left) + font->getWidth(combined_string, 0, mViewModelItem->getFilterStringOffset()) - 2; +        S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD); +        S32 top = getRect().getHeight() - TOP_PAD; +        if(mLabelSuffix.empty() || (font == suffix_font)) +        { +        S32 left = ll_round(text_left) + font->getWidth(combined_string, 0, mViewModelItem->getFilterStringOffset()) - 2;  		S32 right = left + font->getWidth(combined_string, mViewModelItem->getFilterStringOffset(), filter_string_length) + 2; -		S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD); -		S32 top = getRect().getHeight() - TOP_PAD;  		LLUIImage* box_image = default_params.selection_image;  		LLRect box_rect(left, top, right, bottom);  		box_image->draw(box_rect, sFilterBGColor); +        } +        else +        { +            S32 label_filter_length = llmin((S32)mLabel.size() - filter_offset, (S32)filter_string_length); +            if(label_filter_length > 0) +            { +                S32 left = ll_round(text_left) + font->getWidthF32(mLabel, 0, llmin(filter_offset, (S32)mLabel.size())) - 2; +                S32 right = left + font->getWidthF32(mLabel, filter_offset, label_filter_length) + 2; +                LLUIImage* box_image = default_params.selection_image; +                LLRect box_rect(left, top, right, bottom); +                box_image->draw(box_rect, sFilterBGColor); +            } +            S32 suffix_filter_length = label_filter_length > 0 ? filter_string_length - label_filter_length : filter_string_length; +            if(suffix_filter_length > 0) +            { +                S32 suffix_offset = llmax(0, filter_offset - (S32)mLabel.size()); +                S32 left = ll_round(text_left) + font->getWidthF32(mLabel, 0, mLabel.size()) + suffix_font->getWidthF32(mLabelSuffix, 0, suffix_offset) - 2; +                S32 right = left + suffix_font->getWidthF32(mLabelSuffix, suffix_offset, suffix_filter_length) + 2; +                LLUIImage* box_image = default_params.selection_image; +                LLRect box_rect(left, top, right, bottom); +                box_image->draw(box_rect, sFilterBGColor); +            } +        }      }      LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor; @@ -950,7 +995,7 @@ void LLFolderViewItem::draw()  	//  	if (!mLabelSuffix.empty())  	{ -		font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor, +        suffix_font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor,  						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,  						  S32_MAX, S32_MAX, &right_x, FALSE );  	} @@ -960,12 +1005,35 @@ void LLFolderViewItem::draw()  	//      if (filter_string_length > 0)      { -        S32 filter_offset = mViewModelItem->getFilterStringOffset(); -        F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string, filter_offset, filter_string_length); -        F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; -        font->renderUTF8( combined_string, filter_offset, match_string_left, yy, +        if(mLabelSuffix.empty() || (font == suffix_font)) +        { +            F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, filter_offset + filter_string_length) - font->getWidthF32(combined_string, filter_offset, filter_string_length); +            F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; +            font->renderUTF8( combined_string, filter_offset, match_string_left, yy,              sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,              filter_string_length, S32_MAX, &right_x, FALSE ); +        } +        else +        { +            S32 label_filter_length = llmin((S32)mLabel.size() - filter_offset, (S32)filter_string_length); +            if(label_filter_length > 0) +            { +                F32 match_string_left = text_left + font->getWidthF32(mLabel, 0, filter_offset + label_filter_length) - font->getWidthF32(mLabel, filter_offset, label_filter_length); +                F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; +                font->renderUTF8( mLabel, filter_offset, match_string_left, yy, + sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, label_filter_length, S32_MAX, &right_x, FALSE ); +            } +             +            S32 suffix_filter_length = label_filter_length > 0 ? filter_string_length - label_filter_length : filter_string_length; +            if(suffix_filter_length > 0) +            { +                S32 suffix_offset = llmax(0, filter_offset - (S32)mLabel.size()); +                F32 match_string_left = text_left + font->getWidthF32(mLabel, 0, mLabel.size()) + suffix_font->getWidthF32(mLabelSuffix, 0, suffix_offset + suffix_filter_length) - suffix_font->getWidthF32(mLabelSuffix, suffix_offset, suffix_filter_length); +                F32 yy = (F32)getRect().getHeight() - suffix_font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD; +                suffix_font->renderUTF8( mLabelSuffix, suffix_offset, match_string_left, yy, sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, suffix_filter_length, S32_MAX, &right_x, FALSE ); +            } +        } +      }      //Gilbert Linden 9-20-2012: Although this should be legal, removing it because it causes the mLabelSuffix rendering to @@ -1276,7 +1344,7 @@ BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem  			child_selected = TRUE;  		}  	} -	if(openitem && child_selected) +	if(openitem && child_selected && !mSingleFolderMode)  	{  		setOpenArrangeRecursively(TRUE);  	} @@ -1701,6 +1769,11 @@ BOOL LLFolderViewFolder::isRemovable()  	return TRUE;  } +void LLFolderViewFolder::destroyRoot() +{ +    delete this; +} +  // this is an internal method used for adding items to folders.   void LLFolderViewFolder::addItem(LLFolderViewItem* item)  { @@ -1769,7 +1842,19 @@ void LLFolderViewFolder::toggleOpen()  // Force a folder open or closed  void LLFolderViewFolder::setOpen(BOOL openitem)  { -	setOpenArrangeRecursively(openitem); +    if(mSingleFolderMode) +    { +        // navigateToFolder can destroy this view +        // delay it in case setOpen was called from click or key processing +        doOnIdleOneTime([this]() +                        { +                            getViewModelItem()->navigateToFolder(); +                        }); +    } +    else +    { +        setOpenArrangeRecursively(openitem); +    }  }  void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse) @@ -1972,7 +2057,8 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )  	}  	if( !handled )  	{ -		if(mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad) +		if((mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad) +           && !mSingleFolderMode)  		{  			toggleOpen();  			handled = TRUE; @@ -1990,12 +2076,45 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )  BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )  {  	BOOL handled = FALSE; +    if(mSingleFolderMode) +    { +        static LLUICachedControl<bool> double_click_new_window("SingleModeDoubleClickOpenWindow", false); +        if (double_click_new_window) +        { +            getViewModelItem()->navigateToFolder(true); +        } +        else +        { +            // navigating is going to destroy views and change children +            // delay it untill handleDoubleClick processing is complete +            doOnIdleOneTime([this]() +                            { +                                getViewModelItem()->navigateToFolder(false); +                            }); +        } +        return TRUE; +    } +  	if( isOpen() )  	{  		handled = childrenHandleDoubleClick( x, y, mask ) != NULL;  	}  	if( !handled )  	{ +        if(mDoubleClickOverride) +        { +            static LLUICachedControl<U32> double_click_action("MultiModeDoubleClickFolder", false); +            if (double_click_action == 1) +            { +                getViewModelItem()->navigateToFolder(true); +                return TRUE; +            } +            if (double_click_action == 2) +            { +                getViewModelItem()->navigateToFolder(false, true); +                return TRUE; +            } +        }  		if(mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)  		{  			// don't select when user double-clicks plus sign diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h index a5157266c5..5c2a1ecff0 100644 --- a/indra/llui/llfolderviewitem.h +++ b/indra/llui/llfolderviewitem.h @@ -72,6 +72,8 @@ public:                                                      text_pad_right,                                                      arrow_size,                                                      max_folder_item_overlap; +        Optional<bool>                              single_folder_mode, +                                                    double_click_override;  		Params();  	}; @@ -121,6 +123,8 @@ protected:  								mIsMouseOverTitle,  								mAllowWear,                                  mAllowDrop, +                                mSingleFolderMode, +                                mDoubleClickOverride,  								mSelectPending,  								mIsItemCut; @@ -174,7 +178,7 @@ public:  	// Finds width and height of this object and it's children.  Also  	// makes sure that this view and it's children are the right size.  	virtual S32 arrange( S32* width, S32* height ); -	virtual S32 getItemHeight(); +	virtual S32 getItemHeight() const;      virtual S32 getLabelXPos();      S32 getIconPad();      S32 getTextPad(); @@ -213,9 +217,9 @@ public:  	void setIsCurSelection(BOOL select) { mIsCurSelection = select; } -	BOOL getIsCurSelection() { return mIsCurSelection; } +	BOOL getIsCurSelection() const { return mIsCurSelection; } -	BOOL hasVisibleChildren() { return mHasVisibleChildren; } +	BOOL hasVisibleChildren() const { return mHasVisibleChildren; }  	// true if object can't have children  	virtual bool isFolderComplete() { return true; } @@ -264,7 +268,7 @@ public:  	virtual LLFolderView*	getRoot();  	virtual const LLFolderView*	getRoot() const;  	BOOL			isDescendantOf( const LLFolderViewFolder* potential_ancestor ); -	S32				getIndentation() { return mIndentation; } +	S32				getIndentation() const { return mIndentation; }  	virtual BOOL	passedFilter(S32 filter_generation = -1);  	virtual BOOL	isPotentiallyVisible(S32 filter_generation = -1); @@ -277,6 +281,8 @@ public:      // Does not need filter update  	virtual void refreshSuffix(); +    bool isSingleFolderMode() { return mSingleFolderMode; } +  	// LLView functionality  	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );  	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask ); @@ -387,6 +393,7 @@ public:  	// destroys this folder, and all children  	virtual void destroyView(); +    void destroyRoot();      // whether known children are fully loaded (arrange sets to true)      virtual bool isFolderComplete() { return mIsFolderComplete; } diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp index 394581d6d7..96aca62927 100644 --- a/indra/llui/llfolderviewmodel.cpp +++ b/indra/llui/llfolderviewmodel.cpp @@ -34,7 +34,7 @@ bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)  	return item->getSortVersion() < mTargetSortVersion;  } -std::string LLFolderViewModelCommon::getStatusText() +std::string LLFolderViewModelCommon::getStatusText(bool is_empty_folder)  {  	if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter().getCurrentGeneration())  	{ @@ -42,7 +42,7 @@ std::string LLFolderViewModelCommon::getStatusText()  	}  	else  	{ -		return getFilter().getEmptyLookupMessage(); +		return getFilter().getEmptyLookupMessage(is_empty_folder);  	}  } diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index c5e027d314..551a60e097 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -69,7 +69,7 @@ public:  	virtual bool				checkFolder(const LLFolderViewModelItem* folder) const = 0;  	virtual void 				setEmptyLookupMessage(const std::string& message) = 0; -	virtual std::string			getEmptyLookupMessage() const = 0; +    virtual std::string			getEmptyLookupMessage(bool is_empty_folder = false) const = 0;  	virtual bool				showAllResults() const = 0; @@ -125,7 +125,7 @@ public:  	virtual void setFolderView(LLFolderView* folder_view) = 0;  	virtual LLFolderViewFilter& getFilter() = 0;  	virtual const LLFolderViewFilter& getFilter() const = 0; -	virtual std::string getStatusText() = 0; +	virtual std::string getStatusText(bool is_empty_folder = false) = 0;  	virtual bool startDrag(std::vector<LLFolderViewModelItem*>& items) = 0;  }; @@ -159,6 +159,8 @@ public:  	virtual void openItem( void ) = 0;  	virtual void closeItem( void ) = 0;  	virtual void selectItem(void) = 0; + +    virtual void navigateToFolder(bool new_window = false, bool change_mode = false) = 0;      virtual BOOL isItemWearable() const { return FALSE; } @@ -392,7 +394,7 @@ public:  		// sort everything  		mTargetSortVersion++;  	} -	virtual std::string getStatusText(); +	virtual std::string getStatusText(bool is_empty_folder = false);  	virtual void filter();  	void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;} diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h index 5d6c544571..e983d63a01 100644 --- a/indra/llui/lliconctrl.h +++ b/indra/llui/lliconctrl.h @@ -39,7 +39,9 @@ class LLUICtrlFactory;  // Classes  // -//  +// Class for diplaying named UI textures +// Do not use for displaying textures from network, +// UI textures are stored permanently!  class LLIconCtrl  : public LLUICtrl  { diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 7b22f9dbdc..7e4e828a88 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -216,7 +216,8 @@ LLLayoutStack::Params::Params()  	drag_handle_first_indent("drag_handle_first_indent", 0),  	drag_handle_second_indent("drag_handle_second_indent", 0),  	drag_handle_thickness("drag_handle_thickness", 5), -	drag_handle_shift("drag_handle_shift", 2) +	drag_handle_shift("drag_handle_shift", 2), +    drag_handle_color("drag_handle_color", LLUIColorTable::instance().getColor("ResizebarBody"))  {  	addSynonym(border_size, "drag_handle_gap");  } @@ -236,7 +237,8 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)  	mDragHandleFirstIndent(p.drag_handle_first_indent),  	mDragHandleSecondIndent(p.drag_handle_second_indent),  	mDragHandleThickness(p.drag_handle_thickness), -	mDragHandleShift(p.drag_handle_shift) +	mDragHandleShift(p.drag_handle_shift), +    mDragHandleColor(p.drag_handle_color())  {  } @@ -523,6 +525,15 @@ void LLLayoutStack::updateLayout()  	mNeedsLayout = continue_animating;  } // end LLLayoutStack::updateLayout +void LLLayoutStack::setPanelSpacing(S32 val) +{ +    if (mPanelSpacing != val) +    { +        mPanelSpacing = val; +        mNeedsLayout = true; +    } +} +  LLLayoutPanel* LLLayoutStack::findEmbeddedPanel(LLPanel* panelp) const  {  	if (!panelp) return NULL; @@ -576,7 +587,7 @@ void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp)  				resize_bar_bg_panel_p.follows.flags = FOLLOWS_ALL;  				resize_bar_bg_panel_p.tab_stop = false;  				resize_bar_bg_panel_p.background_visible = true; -				resize_bar_bg_panel_p.bg_alpha_color = LLUIColorTable::instance().getColor("ResizebarBody"); +				resize_bar_bg_panel_p.bg_alpha_color = mDragHandleColor;  				resize_bar_bg_panel_p.has_border = true;  				resize_bar_bg_panel_p.border.border_thickness = 1;  				resize_bar_bg_panel_p.border.highlight_light_color = LLUIColorTable::instance().getColor("ResizebarBorderLight"); diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h index 22f11eb20f..000b919ae7 100644 --- a/indra/llui/lllayoutstack.h +++ b/indra/llui/lllayoutstack.h @@ -59,6 +59,8 @@ public:  		Optional<S32>			drag_handle_thickness;  		Optional<S32>			drag_handle_shift; +        Optional<LLUIColor>     drag_handle_color; +  		Params();  	}; @@ -89,6 +91,7 @@ public:  	void updateLayout();  	S32 getPanelSpacing() const { return mPanelSpacing; } +    void setPanelSpacing(S32 val);  	static void updateClass(); @@ -128,6 +131,7 @@ private:  	S32  mDragHandleSecondIndent;  	S32  mDragHandleThickness;  	S32  mDragHandleShift; +    LLUIColor mDragHandleColor;  }; // end class LLLayoutStack diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index fe25ac1647..10da3fb7e0 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -573,13 +573,13 @@ void LLMenuItemGL::onVisibilityChange(BOOL new_visibility)  //  // This class represents a separator.  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LLMenuItemSeparatorGL::Params::Params() -{ -} -  LLMenuItemSeparatorGL::LLMenuItemSeparatorGL(const LLMenuItemSeparatorGL::Params& p) :  	LLMenuItemGL( p )  { +    if (p.on_visible.isProvided()) +    { +        mVisibleSignal.connect(initEnableCallback(p.on_visible)); +    }  }  //virtual @@ -596,6 +596,15 @@ void LLMenuItemSeparatorGL::draw( void )  	gl_line_2d( PAD, y, getRect().getWidth() - PAD, y );  } +void LLMenuItemSeparatorGL::buildDrawLabel( void ) +{ +    if (mVisibleSignal.num_slots() > 0) +    { +        bool visible = mVisibleSignal(this, LLSD()); +        setVisible(visible); +    } +} +  BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask)  {  	LLMenuGL* parent_menu = getMenu(); diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index 9d3be8d94f..87e3f18ebc 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -234,7 +234,9 @@ class LLMenuItemSeparatorGL : public LLMenuItemGL  public:  	struct Params : public LLInitParam::Block<Params, LLMenuItemGL::Params>  	{ -		Params(); +        Optional<EnableCallbackParam > on_visible; +        Params() : on_visible("on_visible") +        {}  	};  	LLMenuItemSeparatorGL(const LLMenuItemSeparatorGL::Params& p = LLMenuItemSeparatorGL::Params()); @@ -243,7 +245,12 @@ public:  	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);  	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask); +    virtual void buildDrawLabel(); +  	/*virtual*/ U32 getNominalHeight( void ) const; + +private: +    enable_signal_t mVisibleSignal;  };  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp index fde6de4921..735e2d529e 100644 --- a/indra/llui/llscrollbar.cpp +++ b/indra/llui/llscrollbar.cpp @@ -188,12 +188,12 @@ void LLScrollbar::setPageSize( S32 page_size )  	}  } -BOOL LLScrollbar::isAtBeginning() +bool LLScrollbar::isAtBeginning() const  {  	return mDocPos == 0;  } -BOOL LLScrollbar::isAtEnd() +bool LLScrollbar::isAtEnd() const  {  	return mDocPos == getDocPosMax();  } @@ -591,7 +591,12 @@ void LLScrollbar::setValue(const LLSD& value)  BOOL LLScrollbar::handleKeyHere(KEY key, MASK mask)  { -	BOOL handled = FALSE; +    if (getDocPosMax() == 0 && !getVisible()) +    { +        return FALSE; +    } + +    BOOL handled = FALSE;  	switch( key )  	{ diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h index 5f2f490d81..9be9d22db8 100644 --- a/indra/llui/llscrollbar.h +++ b/indra/llui/llscrollbar.h @@ -105,8 +105,8 @@ public:  	bool				setDocPos( S32 pos, BOOL update_thumb = TRUE );  	S32					getDocPos() const		{ return mDocPos; } -	BOOL				isAtBeginning(); -	BOOL				isAtEnd(); +	bool				isAtBeginning() const; +	bool				isAtEnd() const;  	// Setting both at once.  	void				setDocParams( S32 size, S32 pos ); diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp index 3db38bbfac..ad32f7186c 100644 --- a/indra/llui/llscrollcontainer.cpp +++ b/indra/llui/llscrollcontainer.cpp @@ -105,8 +105,8 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)  	mBorder = LLUICtrlFactory::create<LLViewBorder> (params);  	LLView::addChild( mBorder ); -	mInnerRect.set( 0, getRect().getHeight(), getRect().getWidth(), 0 ); -	mInnerRect.stretch( -getBorderWidth()  ); +	mInnerRect = getLocalRect(); +	mInnerRect.stretch( -getBorderWidth() );  	LLRect vertical_scroll_rect = mInnerRect;  	vertical_scroll_rect.mLeft = vertical_scroll_rect.mRight - scrollbar_size; @@ -124,8 +124,9 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)  	mScrollbar[VERTICAL] = LLUICtrlFactory::create<LLScrollbar> (sbparams);  	LLView::addChild( mScrollbar[VERTICAL] ); -	LLRect horizontal_scroll_rect = mInnerRect; -	horizontal_scroll_rect.mTop = horizontal_scroll_rect.mBottom + scrollbar_size; +	LLRect horizontal_scroll_rect; +	horizontal_scroll_rect.mTop = scrollbar_size; +	horizontal_scroll_rect.mRight = mInnerRect.getWidth();  	sbparams.name("scrollable horizontal");  	sbparams.rect(horizontal_scroll_rect);  	sbparams.orientation(LLScrollbar::HORIZONTAL); @@ -134,7 +135,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)  	sbparams.page_size(mInnerRect.getWidth());  	sbparams.step_size(VERTICAL_MULTIPLE);  	sbparams.visible(false); -	sbparams.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT); +	sbparams.follows.flags(FOLLOWS_LEFT | FOLLOWS_RIGHT | FOLLOWS_BOTTOM);  	sbparams.change_callback(p.scroll_callback);  	mScrollbar[HORIZONTAL] = LLUICtrlFactory::create<LLScrollbar> (sbparams);  	LLView::addChild( mScrollbar[HORIZONTAL] ); diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h index c14099dbd5..dacea2a987 100644 --- a/indra/llui/llscrollcontainer.h +++ b/indra/llui/llscrollcontainer.h @@ -98,8 +98,10 @@ public:  	void			pageDown(S32 overlap = 0);  	void			goToTop();  	void			goToBottom(); -	bool			isAtTop() { return mScrollbar[VERTICAL]->isAtBeginning(); } -	bool			isAtBottom() { return mScrollbar[VERTICAL]->isAtEnd(); } +	bool			isAtTop() const { return mScrollbar[VERTICAL]->isAtBeginning(); } +	bool			isAtBottom() const { return mScrollbar[VERTICAL]->isAtEnd(); } +    S32             getDocPosVertical() const { return mScrollbar[VERTICAL]->getDocPos(); } +    S32             getDocPosHorizontal() const { return mScrollbar[HORIZONTAL]->getDocPos(); }  	S32				getBorderWidth() const;  	// LLView functionality diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 8c841540a5..76b9e448a1 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -605,6 +605,7 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask )  			LLButton* tab_button = getTab(index)->mButton;  			gFocusMgr.setMouseCapture(this);  			tab_button->setFocus(TRUE); +            mMouseDownTimer.start();  		}  	}  	if (handled) { @@ -653,7 +654,11 @@ BOOL LLTabContainer::handleHover( S32 x, S32 y, MASK mask )  		handled = LLPanel::handleHover(x, y, mask);  	} -	commitHoveredButton(x, y); +    F32 drag_delay = 0.25f; // filter out clicks from dragging +    if (mMouseDownTimer.getElapsedTimeF32() > drag_delay) +    { +        commitHoveredButton(x, y); +    }  	return handled;  } @@ -699,6 +704,7 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask )  	}  	commitHoveredButton(x, y); +    mMouseDownTimer.stop();  	LLPanel* cur_panel = getCurrentPanel();  	if (hasMouseCapture())  	{ @@ -1002,7 +1008,7 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)  	}  	else  	{ -		//Scip tab button space if they are invisible(EXT - 576) +		// Skip tab button space if tabs are invisible (EXT-576)  		tab_panel_top = getRect().getHeight();  		tab_panel_bottom = LLPANEL_BORDER_WIDTH;  	} @@ -1017,9 +1023,9 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)  	}  	else  	{ -		tab_panel_rect = LLRect(LLPANEL_BORDER_WIDTH,  +		tab_panel_rect = LLRect(LLPANEL_BORDER_WIDTH * 3,  								tab_panel_top, -								getRect().getWidth()-LLPANEL_BORDER_WIDTH, +								getRect().getWidth() - LLPANEL_BORDER_WIDTH * 2,  								tab_panel_bottom );  	}  	child->setFollowsAll(); @@ -1106,7 +1112,7 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel)  		  p.follows.flags = p.follows.flags() | FOLLOWS_TOP;  		}  		else -		  {  +		{   		    p.name("htab_"+std::string(child->getName()));  		    p.visible(false);  		    p.image_unselected(tab_img); diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 8f8cedb1b9..aa4a08c4ff 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -320,6 +320,7 @@ private:  	LLUIColor						mTabsFlashingColor;  	S32								mTabIconCtrlPad;  	bool							mUseTabEllipses; +    LLFrameTimer					mMouseDownTimer;  };  #endif  // LL_TABCONTAINER_H diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp index 2f56a8b1d0..a6552d4ff1 100644 --- a/indra/llui/lltooltip.cpp +++ b/indra/llui/lltooltip.cpp @@ -163,6 +163,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)  :	LLPanel(p),  	mHasClickCallback(p.click_callback.isProvided()),  	mPadding(p.padding), +	mMaxWidth(p.max_width),  	mTextBox(NULL),  	mInfoButton(NULL),  	mPlayMediaButton(NULL), @@ -272,7 +273,7 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)  	// do this *after* we've had our size set in LLPanel::initFromParams();  	const S32 REALLY_LARGE_HEIGHT = 10000; -	mTextBox->reshape(p.max_width, REALLY_LARGE_HEIGHT); +	mTextBox->reshape(mMaxWidth, REALLY_LARGE_HEIGHT);  	if (p.styled_message.isProvided())  	{ @@ -288,16 +289,19 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)  		mTextBox->setText(p.message());  	} -	S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth() + 1); +	updateTextBox(); +	snapToChildren(); +} + +void LLToolTip::updateTextBox() +{ +	S32 text_width = llmin(mMaxWidth, mTextBox->getTextPixelWidth() + 1);  	S32 text_height = mTextBox->getTextPixelHeight();  	mTextBox->reshape(text_width, text_height); -	if (mInfoButton) -	{ -		LLRect text_rect = mTextBox->getRect(); -		LLRect icon_rect = mInfoButton->getRect(); -		mTextBox->translate(0, icon_rect.getCenterY() - text_rect.getCenterY()); -	} - +} +  +void LLToolTip::snapToChildren() +{  	// reshape tooltip panel to fit text box  	LLRect tooltip_rect = calcBoundingRect();  	tooltip_rect.mTop += mPadding; @@ -305,7 +309,14 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)  	tooltip_rect.mBottom = 0;  	tooltip_rect.mLeft = 0; -	mTextBox->reshape(mTextBox->getRect().getWidth(), llmax(mTextBox->getRect().getHeight(), tooltip_rect.getHeight() - 2 * mPadding)); +	if (mInfoButton) +	{ +		mTextBox->reshape(mTextBox->getRect().getWidth(), llmax(mTextBox->getRect().getHeight(), tooltip_rect.getHeight() - 2 * mPadding)); + +		LLRect text_rect = mTextBox->getRect(); +		LLRect icon_rect = mInfoButton->getRect(); +		mInfoButton->translate(0, text_rect.getCenterY() - icon_rect.getCenterY()); +	}  	setShape(tooltip_rect);  } @@ -428,7 +439,10 @@ void LLToolTipMgr::createToolTip(const LLToolTip::Params& params)  	}  	tooltip_params.rect = LLRect (0, 1, 1, 0); -	mToolTip = LLUICtrlFactory::create<LLToolTip> (tooltip_params); +	if (tooltip_params.create_callback.isProvided()) +		mToolTip = tooltip_params.create_callback()(tooltip_params); +	else +		mToolTip = LLUICtrlFactory::create<LLToolTip> (tooltip_params);  	gToolTipView->addChild(mToolTip); diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h index 0b1fbe5367..86943625ff 100644 --- a/indra/llui/lltooltip.h +++ b/indra/llui/lltooltip.h @@ -68,6 +68,7 @@ public:  	struct Params : public LLInitParam::Block<Params, LLPanel::Params>   	{  		typedef boost::function<void(void)> click_callback_t; +		typedef boost::function<LLToolTip*(LLToolTip::Params)> create_callback_t;  		Optional<std::string>		message;  		Multiple<StyledText>		styled_message; @@ -84,6 +85,8 @@ public:  		Optional<bool>				time_based_media,  									web_based_media,  									media_playing; +		Optional<create_callback_t>	create_callback; +		Optional<LLSD>				create_params;  		Optional<click_callback_t>	click_callback,  									click_playmedia_callback,  									click_homepage_callback; @@ -103,11 +106,15 @@ public:  	bool hasClickCallback();  	LLToolTip(const Params& p); -	void initFromParams(const LLToolTip::Params& params); +	virtual void initFromParams(const LLToolTip::Params& params);  	void getToolTipMessage(std::string & message); -private: +protected: +	void updateTextBox(); +	void snapToChildren(); + +protected:  	class LLTextBox*	mTextBox;  	class LLButton*     mInfoButton;  	class LLButton*     mPlayMediaButton; @@ -117,6 +124,7 @@ private:  	LLFrameTimer	mVisibleTimer;  	bool			mHasClickCallback;  	S32				mPadding;	// pixels +	S32				mMaxWidth;  };  // used for the inspector tooltips which need different background images etc. diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp index 2196ba201b..21afcae7c3 100644 --- a/indra/llui/lluictrl.cpp +++ b/indra/llui/lluictrl.cpp @@ -531,6 +531,15 @@ void LLUICtrl::setControlVariable(LLControlVariable* control)  	}  } +void LLUICtrl::removeControlVariable() +{ +    if (mControlVariable) +    { +        mControlConnection.disconnect(); +        mControlVariable = NULL; +    } +} +  //virtual  void LLUICtrl::setControlName(const std::string& control_name, LLView *context)  { diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 424b4879ce..ef295976a2 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -176,6 +176,7 @@ public:  	bool setControlValue(const LLSD& value);  	void setControlVariable(LLControlVariable* control);  	virtual void setControlName(const std::string& control, LLView *context = NULL); +    void removeControlVariable();  	LLControlVariable* getControlVariable() { return mControlVariable; }  diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 3344300635..da7868d804 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -311,7 +311,13 @@ bool LLView::addChild(LLView* child, S32 tab_group)  	}  	child->mParentView = this; -	updateBoundingRect(); +    if (getVisible() && child->getVisible()) +    { +        // if child isn't visible it won't affect bounding rect +        // if current view is not visible it will be recalculated +        // on visibility change +        updateBoundingRect(); +    }  	mLastTabGroup = tab_group;  	return true;  } @@ -581,6 +587,7 @@ void LLView::deleteAllChildren()          delete viewp;          mChildList.pop_front();  	} +    updateBoundingRect();  }  void LLView::setAllChildrenEnabled(BOOL b) @@ -879,6 +886,17 @@ LLView*	LLView::childFromPoint(S32 x, S32 y, bool recur)  	return 0;  } +F32 LLView::getTooltipTimeout() +{ +    static LLCachedControl<F32> tooltip_fast_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFastDelay", 0.1f); +    static LLCachedControl<F32> tooltip_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipDelay", 0.7f); +    // allow "scrubbing" over ui by showing next tooltip immediately +    // if previous one was still visible +    return (F32)(LLToolTipMgr::instance().toolTipVisible() +    ? tooltip_fast_delay +    : tooltip_delay); +} +  BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)  {  	BOOL handled = FALSE; @@ -888,14 +906,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)  	std::string tooltip = getToolTip();  	if (!tooltip.empty())  	{ -        static LLCachedControl<F32> tooltip_fast_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipFastDelay", 0.1f); -        static LLCachedControl<F32> tooltip_delay(*LLUI::getInstance()->mSettingGroups["config"], "ToolTipDelay", 0.7f);          static LLCachedControl<bool> allow_ui_tooltips(*LLUI::getInstance()->mSettingGroups["config"], "BasicUITooltips", true); -		// allow "scrubbing" over ui by showing next tooltip immediately -		// if previous one was still visible -		F32 timeout = LLToolTipMgr::instance().toolTipVisible()  -		              ? tooltip_fast_delay -		              : tooltip_delay;  		// Even if we don't show tooltips, consume the event, nothing below should show tooltip  		if (allow_ui_tooltips) @@ -903,7 +914,7 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)  			LLToolTipMgr::instance().show(LLToolTip::Params()  			                              .message(tooltip)  			                              .sticky_rect(calcScreenRect()) -			                              .delay_time(timeout)); +			                              .delay_time(getTooltipTimeout()));  		}  		handled = TRUE;  	} diff --git a/indra/llui/llview.h b/indra/llui/llview.h index 8aa97aac39..7360fd0fb9 100644 --- a/indra/llui/llview.h +++ b/indra/llui/llview.h @@ -243,6 +243,7 @@ public:  	ECursorType	getHoverCursor() { return mHoverCursor; } +    static F32 getTooltipTimeout();  	virtual const std::string getToolTip() const			{ return mToolTipMsg.getString(); }  	void		sendChildToFront(LLView* child);  | 
