summaryrefslogtreecommitdiff
path: root/indra/llui
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llui')
-rw-r--r--indra/llui/llfolderview.cpp28
-rw-r--r--indra/llui/llfolderview.h13
-rw-r--r--indra/llui/llfolderviewitem.cpp131
-rw-r--r--indra/llui/llfolderviewitem.h7
-rw-r--r--indra/llui/llfolderviewmodel.cpp4
-rw-r--r--indra/llui/llfolderviewmodel.h8
-rw-r--r--indra/llui/lliconctrl.h4
-rw-r--r--indra/llui/lllayoutstack.cpp27
-rw-r--r--indra/llui/lllayoutstack.h4
-rw-r--r--indra/llui/llmenugl.cpp24
-rw-r--r--indra/llui/llmenugl.h10
-rw-r--r--indra/llui/lltooltip.cpp36
-rw-r--r--indra/llui/lltooltip.h12
-rw-r--r--indra/llui/lluictrl.cpp9
-rw-r--r--indra/llui/lluictrl.h1
-rw-r--r--indra/llui/llview.cpp35
-rw-r--r--indra/llui/llview.h1
17 files changed, 294 insertions, 60 deletions
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 62c311f522..9fa8a84fa4 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -189,7 +189,8 @@ 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)
{
LLPanel* panel = p.parent_panel;
mParentPanel = panel->getHandle();
@@ -665,7 +666,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
@@ -1273,6 +1274,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())
{
@@ -1532,6 +1538,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 +1738,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)
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 7dfa04828a..22b8c475ec 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -144,6 +144,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,23 +241,27 @@ 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();
void finishRenamingItem( void );
+ void updateRenamerPosition();
// Note: We may eventually have to move that method up the hierarchy to LLFolderViewItem.
LLHandle<LLFolderView> getHandle() const { return getDerivedHandle<LLFolderView>(); }
private:
void updateMenuOptions(LLMenuGL* menu);
- void updateRenamerPosition();
protected:
LLScrollContainer* mScrollContainer; // NULL if this is not a child of a scroll container.
@@ -275,6 +283,7 @@ protected:
LLHandle<LLView> mPopupMenuHandle;
std::string mMenuFileName;
+ LLHandle<LLView> mHoveredItem;
selected_items_t mSelectedItems;
bool mKeyboardSelection,
mAllowMultiSelect,
@@ -330,6 +339,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 eba93beed9..bc7a2cc3f0 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -113,6 +113,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 +153,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 +166,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;
}
@@ -395,7 +399,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;
}
@@ -624,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;
@@ -683,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,
@@ -889,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);
@@ -925,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;
@@ -951,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 );
}
@@ -961,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
@@ -1702,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)
{
@@ -1770,7 +1842,14 @@ void LLFolderViewFolder::toggleOpen()
// Force a folder open or closed
void LLFolderViewFolder::setOpen(BOOL openitem)
{
- setOpenArrangeRecursively(openitem);
+ if(mSingleFolderMode)
+ {
+ getViewModelItem()->navigateToFolder();
+ }
+ else
+ {
+ setOpenArrangeRecursively(openitem);
+ }
}
void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
@@ -1973,7 +2052,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;
@@ -1991,12 +2071,33 @@ 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);
+ getViewModelItem()->navigateToFolder(double_click_new_window);
+ 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..c8d44de474 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;
@@ -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 93122503d1..f217b743a0 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 9c3b517bca..b5aad17ca6 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 77938edf27..08ce31ffc5 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -214,7 +214,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");
}
@@ -234,7 +235,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())
{
}
@@ -282,6 +284,17 @@ void LLLayoutStack::draw()
}
}
+void LLLayoutStack::deleteAllChildren()
+{
+ mPanels.clear();
+ LLView::deleteAllChildren();
+
+ // Not really needed since nothing is left to
+ // display, but for the sake of consistency
+ updateFractionalSizes();
+ mNeedsLayout = true;
+}
+
void LLLayoutStack::removeChild(LLView* view)
{
LLLayoutPanel* embedded_panelp = findEmbeddedPanel(dynamic_cast<LLPanel*>(view));
@@ -289,12 +302,14 @@ void LLLayoutStack::removeChild(LLView* view)
if (embedded_panelp)
{
mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
- delete embedded_panelp;
+ LLView::removeChild(view);
updateFractionalSizes();
mNeedsLayout = true;
}
-
- LLView::removeChild(view);
+ else
+ {
+ LLView::removeChild(view);
+ }
}
BOOL LLLayoutStack::postBuild()
@@ -561,7 +576,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 f772dbc6b4..02685281ef 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();
};
@@ -67,6 +69,7 @@ public:
virtual ~LLLayoutStack();
/*virtual*/ void draw();
+ /*virtual*/ void deleteAllChildren();
/*virtual*/ void removeChild(LLView*);
/*virtual*/ BOOL postBuild();
/*virtual*/ bool addChild(LLView* child, S32 tab_group = 0);
@@ -127,6 +130,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 5cb840fd61..1666ff8c98 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -576,13 +576,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
@@ -599,6 +599,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();
@@ -1882,6 +1891,13 @@ bool LLMenuGL::addContextChild(LLView* view, S32 tab_group)
return false;
}
+
+void LLMenuGL::deleteAllChildren()
+{
+ mItems.clear();
+ LLUICtrl::deleteAllChildren();
+}
+
void LLMenuGL::removeChild( LLView* ctrl)
{
// previously a dynamic_cast with if statement to check validity
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index f84c4d41eb..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;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -442,6 +449,7 @@ public:
/*virtual*/ void drawBackground(LLMenuItemGL* itemp, F32 alpha);
/*virtual*/ void setVisible(BOOL visible);
/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
+ /*virtual*/ void deleteAllChildren();
/*virtual*/ void removeChild( LLView* ctrl);
/*virtual*/ BOOL postBuild();
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 67dd24341c..be1c7dd0b6 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -175,6 +175,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 9ba71913d0..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;
}
@@ -576,9 +582,12 @@ void LLView::deleteAllChildren()
while (!mChildList.empty())
{
- LLView* viewp = mChildList.front();
- delete viewp; // will remove the child from mChildList
+ LLView* viewp = mChildList.front();
+ viewp->mParentView = NULL;
+ delete viewp;
+ mChildList.pop_front();
}
+ updateBoundingRect();
}
void LLView::setAllChildrenEnabled(BOOL b)
@@ -877,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;
@@ -886,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)
@@ -901,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 bec45df78a..444a4c3cb5 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);