Merge branch 'DRTVWR-489' of https://github.com/secondlife/viewer
# Conflicts: # indra/llui/llfloater.cppmaster
commit
548faf2966
|
|
@ -60,7 +60,7 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
|
|||
initNoTabsWidget(params.no_matched_tabs_text);
|
||||
|
||||
mSingleExpansion = params.single_expansion;
|
||||
if(mFitParent && !mSingleExpansion)
|
||||
if (mFitParent && !mSingleExpansion)
|
||||
{
|
||||
LL_INFOS() << "fit_parent works best when combined with single_expansion" << LL_ENDL;
|
||||
}
|
||||
|
|
@ -102,14 +102,13 @@ void LLAccordionCtrl::draw()
|
|||
LLPanel::draw();
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
BOOL LLAccordionCtrl::postBuild()
|
||||
{
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
static LLUICachedControl<S32> scrollbar_size("UIScrollbarSize", 0);
|
||||
|
||||
LLRect scroll_rect;
|
||||
scroll_rect.setOriginAndSize(
|
||||
scroll_rect.setOriginAndSize(
|
||||
getRect().getWidth() - scrollbar_size,
|
||||
1,
|
||||
scrollbar_size,
|
||||
|
|
@ -126,39 +125,42 @@ BOOL LLAccordionCtrl::postBuild()
|
|||
sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
|
||||
sbparams.change_callback(boost::bind(&LLAccordionCtrl::onScrollPosChangeCallback, this, _1, _2));
|
||||
|
||||
mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
|
||||
LLView::addChild( mScrollbar );
|
||||
mScrollbar->setVisible( false );
|
||||
mScrollbar = LLUICtrlFactory::create<LLScrollbar>(sbparams);
|
||||
LLView::addChild(mScrollbar);
|
||||
mScrollbar->setVisible(FALSE);
|
||||
mScrollbar->setFollowsRight();
|
||||
mScrollbar->setFollowsTop();
|
||||
mScrollbar->setFollowsBottom();
|
||||
|
||||
//if it was created from xml...
|
||||
std::vector<LLUICtrl*> accordion_tabs;
|
||||
for(child_list_const_iter_t it = getChildList()->begin();
|
||||
for (child_list_const_iter_t it = getChildList()->begin();
|
||||
getChildList()->end() != it; ++it)
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(*it);
|
||||
if(accordion_tab == NULL)
|
||||
if (accordion_tab == NULL)
|
||||
continue;
|
||||
if(std::find(mAccordionTabs.begin(),mAccordionTabs.end(),accordion_tab) == mAccordionTabs.end())
|
||||
if (std::find(mAccordionTabs.begin(), mAccordionTabs.end(), accordion_tab) == mAccordionTabs.end())
|
||||
{
|
||||
accordion_tabs.push_back(accordion_tab);
|
||||
}
|
||||
}
|
||||
|
||||
for(std::vector<LLUICtrl*>::reverse_iterator it = accordion_tabs.rbegin();it!=accordion_tabs.rend();++it)
|
||||
addCollapsibleCtrl(*it);
|
||||
|
||||
arrange ();
|
||||
|
||||
if(mSingleExpansion)
|
||||
for (std::vector<LLUICtrl*>::reverse_iterator it = accordion_tabs.rbegin();
|
||||
it < accordion_tabs.rend(); ++it)
|
||||
{
|
||||
if(!mAccordionTabs[0]->getDisplayChildren())
|
||||
addCollapsibleCtrl(*it);
|
||||
}
|
||||
|
||||
arrange();
|
||||
|
||||
if (mSingleExpansion)
|
||||
{
|
||||
if (!mAccordionTabs[0]->getDisplayChildren())
|
||||
mAccordionTabs[0]->setDisplayChildren(true);
|
||||
for(size_t i=1;i<mAccordionTabs.size();++i)
|
||||
for (size_t i = 1; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
if(mAccordionTabs[i]->getDisplayChildren())
|
||||
if (mAccordionTabs[i]->getDisplayChildren())
|
||||
mAccordionTabs[i]->setDisplayChildren(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -205,23 +207,22 @@ BOOL LLAccordionCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
|
|||
//---------------------------------------------------------------------------------
|
||||
void LLAccordionCtrl::shiftAccordionTabs(S16 panel_num, S32 delta)
|
||||
{
|
||||
for(size_t i = panel_num; i < mAccordionTabs.size(); i++ )
|
||||
for (size_t i = panel_num; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
ctrlShiftVertical(mAccordionTabs[i],delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
void LLAccordionCtrl::onCollapseCtrlCloseOpen(S16 panel_num)
|
||||
{
|
||||
if(mSingleExpansion)
|
||||
if (mSingleExpansion)
|
||||
{
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
for (size_t i = 0; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
if(i==panel_num)
|
||||
if (i == panel_num)
|
||||
continue;
|
||||
if(mAccordionTabs[i]->getDisplayChildren())
|
||||
if (mAccordionTabs[i]->getDisplayChildren())
|
||||
mAccordionTabs[i]->setDisplayChildren(false);
|
||||
}
|
||||
|
||||
|
|
@ -232,64 +233,63 @@ void LLAccordionCtrl::onCollapseCtrlCloseOpen(S16 panel_num)
|
|||
void LLAccordionCtrl::show_hide_scrollbar(S32 width, S32 height)
|
||||
{
|
||||
calcRecuiredHeight();
|
||||
if(getRecuiredHeight() > height )
|
||||
showScrollbar(width,height);
|
||||
if (getRecuiredHeight() > height)
|
||||
showScrollbar(width, height);
|
||||
else
|
||||
hideScrollbar(width,height);
|
||||
hideScrollbar(width, height);
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::showScrollbar(S32 width, S32 height)
|
||||
void LLAccordionCtrl::showScrollbar(S32 width, S32 height)
|
||||
{
|
||||
bool was_visible = mScrollbar->getVisible();
|
||||
|
||||
mScrollbar->setVisible(true);
|
||||
mScrollbar->setVisible(TRUE);
|
||||
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
|
||||
ctrlSetLeftTopAndSize(mScrollbar
|
||||
,width-scrollbar_size - PARENT_BORDER_MARGIN/2
|
||||
,height-PARENT_BORDER_MARGIN
|
||||
,scrollbar_size
|
||||
,height-2*PARENT_BORDER_MARGIN);
|
||||
, width - scrollbar_size - PARENT_BORDER_MARGIN / 2
|
||||
, height - PARENT_BORDER_MARGIN
|
||||
, scrollbar_size
|
||||
, height - PARENT_BORDER_MARGIN * 2);
|
||||
|
||||
mScrollbar->setPageSize(height);
|
||||
mScrollbar->setDocParams(mInnerRect.getHeight(),mScrollbar->getDocPos());
|
||||
mScrollbar->setDocParams(mInnerRect.getHeight(), mScrollbar->getDocPos());
|
||||
|
||||
if(was_visible)
|
||||
if (was_visible)
|
||||
{
|
||||
S32 scroll_pos = llmin(mScrollbar->getDocPos(), getRecuiredHeight() - height - 1);
|
||||
mScrollbar->setDocPos(scroll_pos);
|
||||
}
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::hideScrollbar( S32 width, S32 height )
|
||||
void LLAccordionCtrl::hideScrollbar(S32 width, S32 height)
|
||||
{
|
||||
if(mScrollbar->getVisible() == false)
|
||||
if (mScrollbar->getVisible() == FALSE)
|
||||
return;
|
||||
mScrollbar->setVisible(false);
|
||||
mScrollbar->setVisible(FALSE);
|
||||
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
|
||||
S32 panel_width = width - 2*BORDER_MARGIN;
|
||||
|
||||
//reshape all accordeons and shift all draggers
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
// Reshape all accordions and shift all draggers
|
||||
for (size_t i = 0; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
LLRect panel_rect = mAccordionTabs[i]->getRect();
|
||||
ctrlSetLeftTopAndSize(mAccordionTabs[i],panel_rect.mLeft,panel_rect.mTop,panel_width,panel_rect.getHeight());
|
||||
ctrlSetLeftTopAndSize(mAccordionTabs[i], panel_rect.mLeft, panel_rect.mTop, panel_width, panel_rect.getHeight());
|
||||
}
|
||||
|
||||
mScrollbar->setDocPos(0);
|
||||
|
||||
if(mAccordionTabs.size()>0)
|
||||
if (!mAccordionTabs.empty())
|
||||
{
|
||||
S32 panel_top = height - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 panel_top = height - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 diff = panel_top - mAccordionTabs[0]->getRect().mTop;
|
||||
shiftAccordionTabs(0,diff);
|
||||
shiftAccordionTabs(0, diff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
S32 LLAccordionCtrl::calcRecuiredHeight()
|
||||
{
|
||||
|
|
@ -305,7 +305,7 @@ S32 LLAccordionCtrl::calcRecuiredHeight()
|
|||
}
|
||||
}
|
||||
|
||||
mInnerRect.setLeftTopAndSize(0,rec_height + BORDER_MARGIN*2,getRect().getWidth(),rec_height + BORDER_MARGIN);
|
||||
mInnerRect.setLeftTopAndSize(0, rec_height + BORDER_MARGIN * 2, getRect().getWidth(), rec_height + BORDER_MARGIN);
|
||||
|
||||
return mInnerRect.getHeight();
|
||||
}
|
||||
|
|
@ -313,7 +313,7 @@ S32 LLAccordionCtrl::calcRecuiredHeight()
|
|||
//---------------------------------------------------------------------------------
|
||||
void LLAccordionCtrl::ctrlSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S32 width, S32 height)
|
||||
{
|
||||
if(!panel)
|
||||
if (!panel)
|
||||
return;
|
||||
LLRect panel_rect = panel->getRect();
|
||||
panel_rect.setLeftTopAndSize( left, top, width, height);
|
||||
|
|
@ -321,9 +321,9 @@ void LLAccordionCtrl::ctrlSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S3
|
|||
panel->setRect(panel_rect);
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::ctrlShiftVertical(LLView* panel,S32 delta)
|
||||
void LLAccordionCtrl::ctrlShiftVertical(LLView* panel, S32 delta)
|
||||
{
|
||||
if(!panel)
|
||||
if (!panel)
|
||||
return;
|
||||
panel->translate(0,delta);
|
||||
}
|
||||
|
|
@ -337,9 +337,9 @@ void LLAccordionCtrl::addCollapsibleCtrl(LLView* view, bool aArrange)
|
|||
// </FS:ND>
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(view);
|
||||
if(!accordion_tab)
|
||||
if (!accordion_tab)
|
||||
return;
|
||||
if(std::find(beginChild(), endChild(), accordion_tab) == endChild())
|
||||
if (std::find(beginChild(), endChild(), accordion_tab) == endChild())
|
||||
addChild(accordion_tab);
|
||||
mAccordionTabs.push_back(accordion_tab);
|
||||
|
||||
|
|
@ -380,7 +380,7 @@ void LLAccordionCtrl::removeCollapsibleCtrl(LLView* view)
|
|||
}
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::initNoTabsWidget(const LLTextBox::Params& tb_params)
|
||||
void LLAccordionCtrl::initNoTabsWidget(const LLTextBox::Params& tb_params)
|
||||
{
|
||||
LLTextBox::Params tp = tb_params;
|
||||
tp.rect(getLocalRect());
|
||||
|
|
@ -388,39 +388,39 @@ void LLAccordionCtrl::initNoTabsWidget(const LLTextBox::Params& tb_params)
|
|||
mNoVisibleTabsHelpText = LLUICtrlFactory::create<LLTextBox>(tp, this);
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::updateNoTabsHelpTextVisibility()
|
||||
void LLAccordionCtrl::updateNoTabsHelpTextVisibility()
|
||||
{
|
||||
bool visible_exists = false;
|
||||
std::vector<LLAccordionCtrlTab*>::const_iterator it = mAccordionTabs.begin();
|
||||
const std::vector<LLAccordionCtrlTab*>::const_iterator it_end = mAccordionTabs.end();
|
||||
for (; it != it_end; ++it)
|
||||
while (it < it_end)
|
||||
{
|
||||
if ((*it)->getVisible())
|
||||
if ((*(it++))->getVisible())
|
||||
{
|
||||
visible_exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mNoVisibleTabsHelpText->setVisible(!visible_exists);
|
||||
mNoVisibleTabsHelpText->setVisible(visible_exists ? FALSE : TRUE);
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::arrangeSinge()
|
||||
void LLAccordionCtrl::arrangeSingle()
|
||||
{
|
||||
S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter
|
||||
S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 panel_width = getRect().getWidth() - 4; // Top coordinate of the first panel
|
||||
S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter
|
||||
S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 panel_width = getRect().getWidth() - 4;
|
||||
S32 panel_height;
|
||||
|
||||
S32 collapsed_height = 0;
|
||||
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
for (size_t i = 0; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]);
|
||||
|
||||
if(accordion_tab->getVisible() == false) //skip hidden accordion tabs
|
||||
if (accordion_tab->getVisible() == FALSE) // Skip hidden accordion tabs
|
||||
continue;
|
||||
if(!accordion_tab->isExpanded() )
|
||||
if (!accordion_tab->isExpanded() )
|
||||
{
|
||||
collapsed_height+=mAccordionTabs[i]->getRect().getHeight();
|
||||
}
|
||||
|
|
@ -428,28 +428,28 @@ void LLAccordionCtrl::arrangeSinge()
|
|||
|
||||
S32 expanded_height = getRect().getHeight() - BORDER_MARGIN - collapsed_height;
|
||||
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
for (size_t i = 0; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]);
|
||||
|
||||
if(accordion_tab->getVisible() == false) //skip hidden accordion tabs
|
||||
if (accordion_tab->getVisible() == FALSE) // Skip hidden accordion tabs
|
||||
continue;
|
||||
if(!accordion_tab->isExpanded() )
|
||||
if (!accordion_tab->isExpanded() )
|
||||
{
|
||||
panel_height = accordion_tab->getRect().getHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mFitParent)
|
||||
if (mFitParent)
|
||||
{
|
||||
panel_height = expanded_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(accordion_tab->getAccordionView())
|
||||
if (accordion_tab->getAccordionView())
|
||||
{
|
||||
panel_height = accordion_tab->getAccordionView()->getRect().getHeight() +
|
||||
accordion_tab->getHeaderHeight() + 2*BORDER_MARGIN;
|
||||
accordion_tab->getHeaderHeight() + BORDER_MARGIN * 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -462,67 +462,67 @@ void LLAccordionCtrl::arrangeSinge()
|
|||
panel_height = llmax(panel_height, accordion_tab->getHeaderHeight());
|
||||
|
||||
ctrlSetLeftTopAndSize(mAccordionTabs[i], panel_left, panel_top, panel_width, panel_height);
|
||||
panel_top-=mAccordionTabs[i]->getRect().getHeight();
|
||||
panel_top -= mAccordionTabs[i]->getRect().getHeight();
|
||||
}
|
||||
|
||||
show_hide_scrollbar(getRect().getWidth(), getRect().getHeight());
|
||||
updateLayout(getRect().getWidth(), getRect().getHeight());
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::arrangeMultiple()
|
||||
void LLAccordionCtrl::arrangeMultiple()
|
||||
{
|
||||
S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter
|
||||
S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 panel_width = getRect().getWidth() - 4; // Top coordinate of the first panel
|
||||
S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter
|
||||
S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 panel_width = getRect().getWidth() - 4;
|
||||
|
||||
//Calculate params
|
||||
for(size_t i = 0; i < mAccordionTabs.size(); i++ )
|
||||
for (size_t i = 0; i < mAccordionTabs.size(); i++ )
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]);
|
||||
|
||||
if(accordion_tab->getVisible() == false) //skip hidden accordion tabs
|
||||
if (accordion_tab->getVisible() == FALSE) // Skip hidden accordion tabs
|
||||
continue;
|
||||
|
||||
if(!accordion_tab->isExpanded() )
|
||||
if (!accordion_tab->isExpanded() )
|
||||
{
|
||||
ctrlSetLeftTopAndSize(mAccordionTabs[i], panel_left, panel_top, panel_width, accordion_tab->getRect().getHeight());
|
||||
panel_top-=mAccordionTabs[i]->getRect().getHeight();
|
||||
panel_top -= mAccordionTabs[i]->getRect().getHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 panel_height = accordion_tab->getRect().getHeight();
|
||||
|
||||
if(mFitParent)
|
||||
if (mFitParent)
|
||||
{
|
||||
// all expanded tabs will have equal height
|
||||
// All expanded tabs will have equal height
|
||||
panel_height = calcExpandedTabHeight(i, panel_top);
|
||||
ctrlSetLeftTopAndSize(accordion_tab, panel_left, panel_top, panel_width, panel_height);
|
||||
|
||||
// try to make accordion tab fit accordion view height.
|
||||
// Try to make accordion tab fit accordion view height.
|
||||
// Accordion View should implement getRequiredRect() and provide valid height
|
||||
S32 optimal_height = accordion_tab->getAccordionView()->getRequiredRect().getHeight();
|
||||
optimal_height += accordion_tab->getHeaderHeight() + 2 * BORDER_MARGIN;
|
||||
if(optimal_height < panel_height)
|
||||
if (optimal_height < panel_height)
|
||||
{
|
||||
panel_height = optimal_height;
|
||||
}
|
||||
|
||||
// minimum tab height is equal to header height
|
||||
if(mAccordionTabs[i]->getHeaderHeight() > panel_height)
|
||||
if (mAccordionTabs[i]->getHeaderHeight() > panel_height)
|
||||
{
|
||||
panel_height = mAccordionTabs[i]->getHeaderHeight();
|
||||
}
|
||||
}
|
||||
|
||||
ctrlSetLeftTopAndSize(mAccordionTabs[i], panel_left, panel_top, panel_width, panel_height);
|
||||
panel_top-=panel_height;
|
||||
panel_top -= panel_height;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
show_hide_scrollbar(getRect().getWidth(),getRect().getHeight());
|
||||
show_hide_scrollbar(getRect().getWidth(), getRect().getHeight());
|
||||
|
||||
updateLayout(getRect().getWidth(),getRect().getHeight());
|
||||
updateLayout(getRect().getWidth(), getRect().getHeight());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -530,70 +530,67 @@ void LLAccordionCtrl::arrange()
|
|||
{
|
||||
updateNoTabsHelpTextVisibility();
|
||||
|
||||
if( mAccordionTabs.size() == 0)
|
||||
if (mAccordionTabs.empty())
|
||||
{
|
||||
//We do not arrange if we do not have what should be arranged
|
||||
// Nothing to arrange
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(mAccordionTabs.size() == 1)
|
||||
if (mAccordionTabs.size() == 1)
|
||||
{
|
||||
S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 panel_width = getRect().getWidth() - 4; // Top coordinate of the first panel
|
||||
S32 panel_top = getRect().getHeight() - BORDER_MARGIN; // Top coordinate of the first panel
|
||||
S32 panel_width = getRect().getWidth() - 4;
|
||||
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[0]);
|
||||
|
||||
LLRect panel_rect = accordion_tab->getRect();
|
||||
|
||||
S32 panel_height = getRect().getHeight() - 2*BORDER_MARGIN;
|
||||
|
||||
S32 panel_height = getRect().getHeight() - BORDER_MARGIN * 2;
|
||||
if (accordion_tab->getFitParent())
|
||||
panel_height = accordion_tab->getRect().getHeight();
|
||||
ctrlSetLeftTopAndSize(accordion_tab,panel_rect.mLeft,panel_top,panel_width,panel_height);
|
||||
|
||||
show_hide_scrollbar(getRect().getWidth(),getRect().getHeight());
|
||||
return;
|
||||
|
||||
ctrlSetLeftTopAndSize(accordion_tab, panel_rect.mLeft, panel_top, panel_width, panel_height);
|
||||
|
||||
show_hide_scrollbar(getRect().getWidth(), getRect().getHeight());
|
||||
return;
|
||||
}
|
||||
|
||||
if(mSingleExpansion)
|
||||
arrangeSinge ();
|
||||
if (mSingleExpansion)
|
||||
arrangeSingle();
|
||||
else
|
||||
arrangeMultiple ();
|
||||
arrangeMultiple();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
|
||||
BOOL LLAccordionCtrl::handleScrollWheel ( S32 x, S32 y, S32 clicks )
|
||||
BOOL LLAccordionCtrl::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
||||
{
|
||||
if(LLPanel::handleScrollWheel(x,y,clicks))
|
||||
if (LLPanel::handleScrollWheel(x, y, clicks))
|
||||
return TRUE;
|
||||
if( mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) )
|
||||
if (mScrollbar->getVisible() && mScrollbar->handleScrollWheel(0, 0, clicks))
|
||||
return TRUE;
|
||||
return false;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LLAccordionCtrl::handleKeyHere (KEY key, MASK mask)
|
||||
BOOL LLAccordionCtrl::handleKeyHere(KEY key, MASK mask)
|
||||
{
|
||||
if( mScrollbar->getVisible() && mScrollbar->handleKeyHere( key,mask ) )
|
||||
if (mScrollbar->getVisible() && mScrollbar->handleKeyHere(key, mask))
|
||||
return TRUE;
|
||||
return LLPanel::handleKeyHere(key,mask);
|
||||
return LLPanel::handleKeyHere(key, mask);
|
||||
}
|
||||
|
||||
BOOL LLAccordionCtrl::handleDragAndDrop (S32 x, S32 y, MASK mask,
|
||||
BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg)
|
||||
BOOL LLAccordionCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg)
|
||||
{
|
||||
// Scroll folder view if needed. Never accepts a drag or drop.
|
||||
*accept = ACCEPT_NO;
|
||||
BOOL handled = autoScroll(x, y);
|
||||
|
||||
if( !handled )
|
||||
if (!handled)
|
||||
{
|
||||
handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
|
||||
cargo_data, accept, tooltip_msg) != NULL;
|
||||
|
|
@ -601,14 +598,14 @@ BOOL LLAccordionCtrl::handleDragAndDrop (S32 x, S32 y, MASK mask,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLAccordionCtrl::autoScroll (S32 x, S32 y)
|
||||
BOOL LLAccordionCtrl::autoScroll(S32 x, S32 y)
|
||||
{
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
|
||||
bool scrolling = false;
|
||||
if( mScrollbar->getVisible() )
|
||||
if (mScrollbar->getVisible())
|
||||
{
|
||||
LLRect rect_local( 0, getRect().getHeight(), getRect().getWidth() - scrollbar_size, 0 );
|
||||
LLRect rect_local(0, getRect().getHeight(), getRect().getWidth() - scrollbar_size, 0);
|
||||
LLRect screen_local_extents;
|
||||
|
||||
// clip rect against root view
|
||||
|
|
@ -621,51 +618,52 @@ BOOL LLAccordionCtrl::autoScroll (S32 x, S32 y)
|
|||
|
||||
LLRect bottom_scroll_rect = screen_local_extents;
|
||||
bottom_scroll_rect.mTop = rect_local.mBottom + auto_scroll_region_height;
|
||||
if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar->getDocPos() < mScrollbar->getDocPosMax()) )
|
||||
if (bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar->getDocPos() < mScrollbar->getDocPosMax()))
|
||||
{
|
||||
mScrollbar->setDocPos( mScrollbar->getDocPos() + auto_scroll_speed );
|
||||
mScrollbar->setDocPos(mScrollbar->getDocPos() + auto_scroll_speed);
|
||||
mAutoScrolling = true;
|
||||
scrolling = true;
|
||||
}
|
||||
|
||||
LLRect top_scroll_rect = screen_local_extents;
|
||||
top_scroll_rect.mBottom = rect_local.mTop - auto_scroll_region_height;
|
||||
if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar->getDocPos() > 0) )
|
||||
if (top_scroll_rect.pointInRect(x, y) && (mScrollbar->getDocPos() > 0))
|
||||
{
|
||||
mScrollbar->setDocPos( mScrollbar->getDocPos() - auto_scroll_speed );
|
||||
mScrollbar->setDocPos(mScrollbar->getDocPos() - auto_scroll_speed);
|
||||
mAutoScrolling = true;
|
||||
scrolling = true;
|
||||
}
|
||||
}
|
||||
return scrolling;
|
||||
|
||||
return scrolling ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::updateLayout (S32 width, S32 height)
|
||||
void LLAccordionCtrl::updateLayout(S32 width, S32 height)
|
||||
{
|
||||
S32 panel_top = height - BORDER_MARGIN ;
|
||||
if(mScrollbar->getVisible())
|
||||
panel_top+=mScrollbar->getDocPos();
|
||||
if (mScrollbar->getVisible())
|
||||
panel_top += mScrollbar->getDocPos();
|
||||
|
||||
S32 panel_width = width - 2*BORDER_MARGIN;
|
||||
S32 panel_width = width - BORDER_MARGIN * 2;
|
||||
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
if(mScrollbar->getVisible())
|
||||
panel_width-=scrollbar_size;
|
||||
if (mScrollbar->getVisible())
|
||||
panel_width -= scrollbar_size;
|
||||
|
||||
//set sizes for first panels and dragbars
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
// set sizes for first panels and dragbars
|
||||
for (size_t i = 0; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
if(!mAccordionTabs[i]->getVisible())
|
||||
if (!mAccordionTabs[i]->getVisible())
|
||||
continue;
|
||||
LLRect panel_rect = mAccordionTabs[i]->getRect();
|
||||
ctrlSetLeftTopAndSize(mAccordionTabs[i],panel_rect.mLeft,panel_top,panel_width,panel_rect.getHeight());
|
||||
panel_top-=panel_rect.getHeight();
|
||||
ctrlSetLeftTopAndSize(mAccordionTabs[i], panel_rect.mLeft, panel_top, panel_width, panel_rect.getHeight());
|
||||
panel_top -= panel_rect.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
|
||||
void LLAccordionCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
|
||||
{
|
||||
updateLayout(getRect().getWidth(),getRect().getHeight());
|
||||
updateLayout(getRect().getWidth(), getRect().getHeight());
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
|
@ -698,42 +696,43 @@ void LLAccordionCtrl::onUpdateScrollToChild(const LLUICtrl *cntrl)
|
|||
LLUICtrl::onUpdateScrollToChild(cntrl);
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::onOpen (const LLSD& key)
|
||||
void LLAccordionCtrl::onOpen(const LLSD& key)
|
||||
{
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
for (size_t i = 0; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]);
|
||||
LLPanel* panel = dynamic_cast<LLPanel*>(accordion_tab->getAccordionView());
|
||||
if(panel!=NULL)
|
||||
if (panel != NULL)
|
||||
{
|
||||
panel->onOpen(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLAccordionCtrl::notifyParent(const LLSD& info)
|
||||
{
|
||||
if(info.has("action"))
|
||||
if (info.has("action"))
|
||||
{
|
||||
std::string str_action = info["action"];
|
||||
if(str_action == "size_changes")
|
||||
if (str_action == "size_changes")
|
||||
{
|
||||
//
|
||||
arrange();
|
||||
return 1;
|
||||
}
|
||||
else if(str_action == "select_next")
|
||||
if (str_action == "select_next")
|
||||
{
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
for (size_t i = 0; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]);
|
||||
if(accordion_tab->hasFocus())
|
||||
if (accordion_tab->hasFocus())
|
||||
{
|
||||
while(++i<mAccordionTabs.size())
|
||||
while (++i < mAccordionTabs.size())
|
||||
{
|
||||
if(mAccordionTabs[i]->getVisible())
|
||||
if (mAccordionTabs[i]->getVisible())
|
||||
break;
|
||||
}
|
||||
if(i<mAccordionTabs.size())
|
||||
if (i < mAccordionTabs.size())
|
||||
{
|
||||
accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]);
|
||||
accordion_tab->notify(LLSD().with("action","select_first"));
|
||||
|
|
@ -744,17 +743,17 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
else if(str_action == "select_prev")
|
||||
if (str_action == "select_prev")
|
||||
{
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
for (size_t i = 0; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(mAccordionTabs[i]);
|
||||
if(accordion_tab->hasFocus() && i>0)
|
||||
if (accordion_tab->hasFocus() && i > 0)
|
||||
{
|
||||
bool prev_visible_tab_found = false;
|
||||
while(i>0)
|
||||
while (i > 0)
|
||||
{
|
||||
if(mAccordionTabs[--i]->getVisible())
|
||||
if (mAccordionTabs[--i]->getVisible())
|
||||
{
|
||||
prev_visible_tab_found = true;
|
||||
break;
|
||||
|
|
@ -772,12 +771,12 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
else if(str_action == "select_current")
|
||||
if (str_action == "select_current")
|
||||
{
|
||||
for(size_t i=0;i<mAccordionTabs.size();++i)
|
||||
for (size_t i = 0; i < mAccordionTabs.size(); ++i)
|
||||
{
|
||||
// Set selection to the currently focused tab.
|
||||
if(mAccordionTabs[i]->hasFocus())
|
||||
if (mAccordionTabs[i]->hasFocus())
|
||||
{
|
||||
if (mAccordionTabs[i] != mSelectedTab)
|
||||
{
|
||||
|
|
@ -794,7 +793,7 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
else if(str_action == "deselect_current")
|
||||
if (str_action == "deselect_current")
|
||||
{
|
||||
// Reset selection to the currently selected tab.
|
||||
if (mSelectedTab)
|
||||
|
|
@ -813,9 +812,9 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info)
|
|||
screenRectToLocal(screen_rc, &local_rc);
|
||||
|
||||
// Translate to parent coordinatess to check if we are in visible rectangle
|
||||
local_rc.translate( getRect().mLeft, getRect().mBottom );
|
||||
local_rc.translate(getRect().mLeft, getRect().mBottom);
|
||||
|
||||
if ( !getRect().contains (local_rc) )
|
||||
if (!getRect().contains (local_rc))
|
||||
{
|
||||
// Back to local coords and calculate position for scroller
|
||||
S32 bottom = mScrollbar->getDocPos() - local_rc.mBottom + getRect().mBottom;
|
||||
|
|
@ -825,7 +824,7 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info)
|
|||
bottom, // min vertical scroll
|
||||
top); // max vertical scroll
|
||||
|
||||
mScrollbar->setDocPos( scroll_pos );
|
||||
mScrollbar->setDocPos(scroll_pos);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -845,15 +844,16 @@ S32 LLAccordionCtrl::notifyParent(const LLSD& info)
|
|||
}
|
||||
return LLPanel::notifyParent(info);
|
||||
}
|
||||
void LLAccordionCtrl::reset ()
|
||||
|
||||
void LLAccordionCtrl::reset()
|
||||
{
|
||||
if(mScrollbar)
|
||||
if (mScrollbar)
|
||||
mScrollbar->setDocPos(0);
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::expandDefaultTab()
|
||||
{
|
||||
if (mAccordionTabs.size() > 0)
|
||||
if (!mAccordionTabs.empty())
|
||||
{
|
||||
LLAccordionCtrlTab* tab = mAccordionTabs.front();
|
||||
|
||||
|
|
@ -888,7 +888,7 @@ void LLAccordionCtrl::sort()
|
|||
arrange();
|
||||
}
|
||||
|
||||
void LLAccordionCtrl::setFilterSubString(const std::string& filter_string)
|
||||
void LLAccordionCtrl::setFilterSubString(const std::string& filter_string)
|
||||
{
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[SEARCH_TERM]"] = LLURI::escape(filter_string);
|
||||
|
|
@ -918,7 +918,7 @@ const LLAccordionCtrlTab* LLAccordionCtrl::getExpandedTab() const
|
|||
|
||||
S32 LLAccordionCtrl::calcExpandedTabHeight(S32 tab_index /* = 0 */, S32 available_height /* = 0 */)
|
||||
{
|
||||
if(tab_index < 0)
|
||||
if (tab_index < 0)
|
||||
{
|
||||
return available_height;
|
||||
}
|
||||
|
|
@ -926,9 +926,9 @@ S32 LLAccordionCtrl::calcExpandedTabHeight(S32 tab_index /* = 0 */, S32 availabl
|
|||
S32 collapsed_tabs_height = 0;
|
||||
S32 num_expanded = 0;
|
||||
|
||||
for(size_t n = tab_index; n < mAccordionTabs.size(); ++n)
|
||||
for (size_t n = tab_index; n < mAccordionTabs.size(); ++n)
|
||||
{
|
||||
if(!mAccordionTabs[n]->isExpanded())
|
||||
if (!mAccordionTabs[n]->isExpanded())
|
||||
{
|
||||
collapsed_tabs_height += mAccordionTabs[n]->getHeaderHeight();
|
||||
}
|
||||
|
|
@ -938,7 +938,7 @@ S32 LLAccordionCtrl::calcExpandedTabHeight(S32 tab_index /* = 0 */, S32 availabl
|
|||
}
|
||||
}
|
||||
|
||||
if(0 == num_expanded)
|
||||
if (0 == num_expanded)
|
||||
{
|
||||
return available_height;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ private:
|
|||
void initNoTabsWidget(const LLTextBox::Params& tb_params);
|
||||
void updateNoTabsHelpTextVisibility();
|
||||
|
||||
void arrangeSinge();
|
||||
void arrangeSingle();
|
||||
void arrangeMultiple();
|
||||
|
||||
// Calc Splitter's height that is necessary to display all child content
|
||||
|
|
|
|||
|
|
@ -69,13 +69,13 @@ public:
|
|||
virtual BOOL postBuild();
|
||||
|
||||
std::string getTitle();
|
||||
void setTitle(const std::string& title, const std::string& hl);
|
||||
void setTitle(const std::string& title, const std::string& hl);
|
||||
|
||||
void setTitleFontStyle(std::string style);
|
||||
void setTitleFontStyle(std::string style);
|
||||
|
||||
void setTitleColor(LLUIColor);
|
||||
void setTitleColor(LLUIColor);
|
||||
|
||||
void setSelected(bool is_selected) { mIsSelected = is_selected; }
|
||||
void setSelected(bool is_selected) { mIsSelected = is_selected; }
|
||||
|
||||
virtual void onMouseEnter(S32 x, S32 y, MASK mask);
|
||||
virtual void onMouseLeave(S32 x, S32 y, MASK mask);
|
||||
|
|
@ -85,8 +85,8 @@ public:
|
|||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
private:
|
||||
|
||||
private:
|
||||
LLTextBox* mHeaderTextbox;
|
||||
|
||||
// Overlay images (arrows)
|
||||
|
|
@ -102,7 +102,7 @@ private:
|
|||
LLPointer<LLUIImage> mImageHeaderFocused;
|
||||
|
||||
// style saved when applying it in setTitleFontStyle
|
||||
LLStyle::Params mStyleParams;
|
||||
LLStyle::Params mStyleParams;
|
||||
|
||||
LLUIColor mHeaderBGColor;
|
||||
|
||||
|
|
@ -157,19 +157,17 @@ BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::postBuild()
|
|||
|
||||
std::string LLAccordionCtrlTab::LLAccordionCtrlTabHeader::getTitle()
|
||||
{
|
||||
if(mHeaderTextbox)
|
||||
if (mHeaderTextbox)
|
||||
{
|
||||
return mHeaderTextbox->getText();
|
||||
}
|
||||
else
|
||||
{
|
||||
return LLStringUtil::null;
|
||||
}
|
||||
|
||||
return LLStringUtil::null;
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitle(const std::string& title, const std::string& hl)
|
||||
{
|
||||
if(mHeaderTextbox)
|
||||
if (mHeaderTextbox)
|
||||
{
|
||||
LLTextUtil::textboxSetHighlightedVal(
|
||||
mHeaderTextbox,
|
||||
|
|
@ -192,7 +190,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitleFontStyle(std::string
|
|||
|
||||
void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitleColor(LLUIColor color)
|
||||
{
|
||||
if(mHeaderTextbox)
|
||||
if (mHeaderTextbox)
|
||||
{
|
||||
mHeaderTextbox->setColor(color);
|
||||
}
|
||||
|
|
@ -204,11 +202,11 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
|
|||
S32 height = getRect().getHeight();
|
||||
|
||||
F32 alpha = getCurrentTransparency();
|
||||
gl_rect_2d(0,0,width - 1 ,height - 1,mHeaderBGColor.get() % alpha,true);
|
||||
gl_rect_2d(0, 0, width - 1, height - 1, mHeaderBGColor.get() % alpha, TRUE);
|
||||
|
||||
LLAccordionCtrlTab* parent = dynamic_cast<LLAccordionCtrlTab*>(getParent());
|
||||
bool collapsible = (parent && parent->getCollapsible());
|
||||
bool expanded = (parent && parent->getDisplayChildren());
|
||||
bool collapsible = parent && parent->getCollapsible();
|
||||
bool expanded = parent && parent->getDisplayChildren();
|
||||
|
||||
// Handle overlay images, if needed
|
||||
// Only show green "focus" background image if the accordion is open,
|
||||
|
|
@ -218,23 +216,22 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
|
|||
/*&& !(collapsible && !expanded)*/ // WHY??
|
||||
)
|
||||
{
|
||||
mImageHeaderFocused->draw(0,0,width,height);
|
||||
mImageHeaderFocused->draw(0, 0, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
mImageHeader->draw(0,0,width,height);
|
||||
mImageHeader->draw(0, 0, width, height);
|
||||
}
|
||||
|
||||
if(mNeedsHighlight)
|
||||
if (mNeedsHighlight)
|
||||
{
|
||||
mImageHeaderOver->draw(0,0,width,height);
|
||||
mImageHeaderOver->draw(0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
if(collapsible)
|
||||
if (collapsible)
|
||||
{
|
||||
LLPointer<LLUIImage> overlay_image;
|
||||
if(expanded)
|
||||
if (expanded)
|
||||
{
|
||||
overlay_image = mImageExpanded;
|
||||
}
|
||||
|
|
@ -242,8 +239,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
|
|||
{
|
||||
overlay_image = mImageCollapsed;
|
||||
}
|
||||
overlay_image->draw(HEADER_IMAGE_LEFT_OFFSET,
|
||||
(height - overlay_image->getHeight()) / 2);
|
||||
overlay_image->draw(HEADER_IMAGE_LEFT_OFFSET, (height - overlay_image->getHeight()) / 2);
|
||||
}
|
||||
|
||||
LLUICtrl::draw();
|
||||
|
|
@ -253,7 +249,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::reshape(S32 width, S32 height
|
|||
{
|
||||
S32 header_height = mHeaderTextbox->getTextPixelHeight();
|
||||
|
||||
LLRect textboxRect(HEADER_TEXT_LEFT_OFFSET,(height+header_height)/2 ,width,(height-header_height)/2);
|
||||
LLRect textboxRect(HEADER_TEXT_LEFT_OFFSET, (height + header_height) / 2, width, (height - header_height) / 2);
|
||||
mHeaderTextbox->reshape(textboxRect.getWidth(), textboxRect.getHeight());
|
||||
mHeaderTextbox->setRect(textboxRect);
|
||||
|
||||
|
|
@ -272,20 +268,24 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::onMouseEnter(S32 x, S32 y, MA
|
|||
LLUICtrl::onMouseEnter(x, y, mask);
|
||||
mNeedsHighlight = true;
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::onMouseLeave(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
LLUICtrl::onMouseLeave(x, y, mask);
|
||||
mNeedsHighlight = false;
|
||||
mAutoOpenTimer.stop();
|
||||
}
|
||||
|
||||
BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
||||
{
|
||||
if ( ( key == KEY_LEFT || key == KEY_RIGHT) && mask == MASK_NONE)
|
||||
if ((key == KEY_LEFT || key == KEY_RIGHT) && mask == MASK_NONE)
|
||||
{
|
||||
return getParent()->handleKey(key, mask, called_from_parent);
|
||||
}
|
||||
|
||||
return LLUICtrl::handleKey(key, mask, called_from_parent);
|
||||
}
|
||||
|
||||
BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleDragAndDrop(S32 x, S32 y, MASK mask,
|
||||
BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
|
|
@ -295,7 +295,7 @@ BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleDragAndDrop(S32 x, S32
|
|||
{
|
||||
LLAccordionCtrlTab* parent = dynamic_cast<LLAccordionCtrlTab*>(getParent());
|
||||
|
||||
if ( parent && !parent->getDisplayChildren() && parent->getCollapsible() && parent->canOpenClose() )
|
||||
if (parent && !parent->getDisplayChildren() && parent->getCollapsible() && parent->canOpenClose())
|
||||
{
|
||||
if (mAutoOpenTimer.getStarted())
|
||||
{
|
||||
|
|
@ -307,12 +307,15 @@ BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleDragAndDrop(S32 x, S32
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mAutoOpenTimer.start();
|
||||
}
|
||||
}
|
||||
|
||||
return LLUICtrl::handleDragAndDrop(x, y, mask, drop, cargo_type,
|
||||
cargo_data, accept, tooltip_msg);
|
||||
}
|
||||
|
||||
LLAccordionCtrlTab::Params::Params()
|
||||
: title("title")
|
||||
,display_children("expanded", true)
|
||||
|
|
@ -384,41 +387,39 @@ LLAccordionCtrlTab::~LLAccordionCtrlTab()
|
|||
{
|
||||
}
|
||||
|
||||
|
||||
void LLAccordionCtrlTab::setDisplayChildren(bool display)
|
||||
{
|
||||
mDisplayChildren = display;
|
||||
LLRect rect = getRect();
|
||||
|
||||
rect.mBottom = rect.mTop - (getDisplayChildren() ?
|
||||
mExpandedHeight : HEADER_HEIGHT);
|
||||
rect.mBottom = rect.mTop - (getDisplayChildren() ? mExpandedHeight : HEADER_HEIGHT);
|
||||
setRect(rect);
|
||||
|
||||
if(mContainerPanel)
|
||||
if (mContainerPanel)
|
||||
{
|
||||
mContainerPanel->setVisible(getDisplayChildren());
|
||||
}
|
||||
|
||||
if(mDisplayChildren)
|
||||
if (mDisplayChildren)
|
||||
{
|
||||
adjustContainerPanel();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mScrollbar)
|
||||
mScrollbar->setVisible(false);
|
||||
if (mScrollbar)
|
||||
mScrollbar->setVisible(FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
|
||||
{
|
||||
LLRect headerRect;
|
||||
|
||||
headerRect.setLeftTopAndSize(
|
||||
0,height,width,HEADER_HEIGHT);
|
||||
headerRect.setLeftTopAndSize(0, height, width, HEADER_HEIGHT);
|
||||
mHeader->setRect(headerRect);
|
||||
mHeader->reshape(headerRect.getWidth(), headerRect.getHeight());
|
||||
|
||||
if(!mDisplayChildren)
|
||||
if (!mDisplayChildren)
|
||||
return;
|
||||
|
||||
LLRect childRect;
|
||||
|
|
@ -426,7 +427,7 @@ void LLAccordionCtrlTab::reshape(S32 width, S32 height, BOOL called_from_parent
|
|||
childRect.setLeftTopAndSize(
|
||||
getPaddingLeft(),
|
||||
height - getHeaderHeight() - getPaddingTop(),
|
||||
width - getPaddingLeft() - getPaddingRight(),
|
||||
width - getPaddingLeft() - getPaddingRight(),
|
||||
height - getHeaderHeight() - getPaddingTop() - getPaddingBottom() );
|
||||
|
||||
adjustContainerPanel(childRect);
|
||||
|
|
@ -434,7 +435,7 @@ void LLAccordionCtrlTab::reshape(S32 width, S32 height, BOOL called_from_parent
|
|||
|
||||
void LLAccordionCtrlTab::changeOpenClose(bool is_open)
|
||||
{
|
||||
if(is_open)
|
||||
if (is_open)
|
||||
mExpandedHeight = getRect().getHeight();
|
||||
|
||||
setDisplayChildren(!is_open);
|
||||
|
|
@ -483,14 +484,14 @@ void LLAccordionCtrlTab::onUpdateScrollToChild(const LLUICtrl *cntrl)
|
|||
|
||||
BOOL LLAccordionCtrlTab::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
if(mCollapsible && mHeaderVisible && mCanOpenClose)
|
||||
if (mCollapsible && mHeaderVisible && mCanOpenClose)
|
||||
{
|
||||
if(y >= (getRect().getHeight() - HEADER_HEIGHT) )
|
||||
if (y >= (getRect().getHeight() - HEADER_HEIGHT))
|
||||
{
|
||||
mHeader->setFocus(true);
|
||||
changeOpenClose(getDisplayChildren());
|
||||
|
||||
//reset stored state
|
||||
// Reset stored state
|
||||
mWasStateStored = false;
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -510,7 +511,7 @@ boost::signals2::connection LLAccordionCtrlTab::setDropDownStateChangedCallback(
|
|||
|
||||
bool LLAccordionCtrlTab::addChild(LLView* child, S32 tab_group)
|
||||
{
|
||||
if(DD_HEADER_NAME != child->getName())
|
||||
if (DD_HEADER_NAME != child->getName())
|
||||
{
|
||||
reshape(child->getRect().getWidth() , child->getRect().getHeight() + HEADER_HEIGHT );
|
||||
mExpandedHeight = getRect().getHeight();
|
||||
|
|
@ -518,12 +519,12 @@ bool LLAccordionCtrlTab::addChild(LLView* child, S32 tab_group)
|
|||
|
||||
bool res = LLUICtrl::addChild(child, tab_group);
|
||||
|
||||
if(DD_HEADER_NAME != child->getName())
|
||||
if (DD_HEADER_NAME != child->getName())
|
||||
{
|
||||
if(!mCollapsible)
|
||||
if (!mCollapsible)
|
||||
setDisplayChildren(true);
|
||||
else
|
||||
setDisplayChildren(getDisplayChildren());
|
||||
setDisplayChildren(getDisplayChildren());
|
||||
}
|
||||
|
||||
if (!mContainerPanel)
|
||||
|
|
@ -534,7 +535,7 @@ bool LLAccordionCtrlTab::addChild(LLView* child, S32 tab_group)
|
|||
|
||||
void LLAccordionCtrlTab::setAccordionView(LLView* panel)
|
||||
{
|
||||
addChild(panel,0);
|
||||
addChild(panel, 0);
|
||||
}
|
||||
|
||||
std::string LLAccordionCtrlTab::getTitle() const
|
||||
|
|
@ -543,10 +544,8 @@ std::string LLAccordionCtrlTab::getTitle() const
|
|||
{
|
||||
return mHeader->getTitle();
|
||||
}
|
||||
else
|
||||
{
|
||||
return LLStringUtil::null;
|
||||
}
|
||||
|
||||
return LLStringUtil::null;
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::setTitle(const std::string& title, const std::string& hl)
|
||||
|
|
@ -579,6 +578,7 @@ boost::signals2::connection LLAccordionCtrlTab::setFocusReceivedCallback(const f
|
|||
{
|
||||
return mHeader->setFocusReceivedCallback(cb);
|
||||
}
|
||||
|
||||
return boost::signals2::connection();
|
||||
}
|
||||
|
||||
|
|
@ -588,6 +588,7 @@ boost::signals2::connection LLAccordionCtrlTab::setFocusLostCallback(const focus
|
|||
{
|
||||
return mHeader->setFocusLostCallback(cb);
|
||||
}
|
||||
|
||||
return boost::signals2::connection();
|
||||
}
|
||||
|
||||
|
|
@ -601,59 +602,65 @@ void LLAccordionCtrlTab::setSelected(bool is_selected)
|
|||
|
||||
LLView* LLAccordionCtrlTab::findContainerView()
|
||||
{
|
||||
for(child_list_const_iter_t it = getChildList()->begin();
|
||||
getChildList()->end() != it; ++it)
|
||||
child_list_const_iter_t it = getChildList()->begin(), it_end = getChildList()->end();
|
||||
while (it != it_end)
|
||||
{
|
||||
LLView* child = *it;
|
||||
if(DD_HEADER_NAME == child->getName())
|
||||
continue;
|
||||
if(!child->getVisible())
|
||||
continue;
|
||||
return child;
|
||||
LLView* child = *(it++);
|
||||
if (DD_HEADER_NAME != child->getName() && child->getVisible())
|
||||
return child;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::selectOnFocusReceived()
|
||||
{
|
||||
if (getParent()) // A parent may not be set if tabs are added dynamically.
|
||||
{
|
||||
getParent()->notifyParent(LLSD().with("action", "select_current"));
|
||||
}
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::deselectOnFocusLost()
|
||||
{
|
||||
if(getParent()) // A parent may not be set if tabs are added dynamically.
|
||||
if (getParent()) // A parent may not be set if tabs are added dynamically.
|
||||
{
|
||||
getParent()->notifyParent(LLSD().with("action", "deselect_current"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
S32 LLAccordionCtrlTab::getHeaderHeight()
|
||||
{
|
||||
return mHeaderVisible?HEADER_HEIGHT:0;
|
||||
return mHeaderVisible ? HEADER_HEIGHT : 0;
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::setHeaderVisible(bool value)
|
||||
void LLAccordionCtrlTab::setHeaderVisible(bool value)
|
||||
{
|
||||
if(mHeaderVisible == value)
|
||||
if (mHeaderVisible == value)
|
||||
return;
|
||||
|
||||
mHeaderVisible = value;
|
||||
if(mHeader)
|
||||
mHeader->setVisible(value);
|
||||
|
||||
if (mHeader)
|
||||
{
|
||||
mHeader->setVisible(value ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
reshape(getRect().getWidth(), getRect().getHeight(), FALSE);
|
||||
};
|
||||
|
||||
//virtual
|
||||
BOOL LLAccordionCtrlTab::postBuild()
|
||||
{
|
||||
if(mHeader)
|
||||
if (mHeader)
|
||||
{
|
||||
mHeader->setVisible(mHeaderVisible);
|
||||
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
}
|
||||
|
||||
static LLUICachedControl<S32> scrollbar_size("UIScrollbarSize", 0);
|
||||
|
||||
LLRect scroll_rect;
|
||||
scroll_rect.setOriginAndSize(
|
||||
scroll_rect.setOriginAndSize(
|
||||
getRect().getWidth() - scrollbar_size,
|
||||
1,
|
||||
scrollbar_size,
|
||||
|
|
@ -661,7 +668,7 @@ BOOL LLAccordionCtrlTab::postBuild()
|
|||
|
||||
mContainerPanel = findContainerView();
|
||||
|
||||
if(!mFitPanel)
|
||||
if (!mFitPanel)
|
||||
{
|
||||
LLScrollbar::Params sbparams;
|
||||
sbparams.name("scrollable vertical");
|
||||
|
|
@ -674,9 +681,8 @@ BOOL LLAccordionCtrlTab::postBuild()
|
|||
sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
|
||||
sbparams.change_callback(boost::bind(&LLAccordionCtrlTab::onScrollPosChangeCallback, this, _1, _2));
|
||||
|
||||
|
||||
mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
|
||||
LLView::addChild( mScrollbar );
|
||||
mScrollbar = LLUICtrlFactory::create<LLScrollbar>(sbparams);
|
||||
LLView::addChild(mScrollbar);
|
||||
mScrollbar->setFollowsRight();
|
||||
mScrollbar->setFollowsTop();
|
||||
mScrollbar->setFollowsBottom();
|
||||
|
|
@ -684,44 +690,48 @@ BOOL LLAccordionCtrlTab::postBuild()
|
|||
mScrollbar->setVisible(false);
|
||||
}
|
||||
|
||||
if(mContainerPanel)
|
||||
if (mContainerPanel)
|
||||
{
|
||||
mContainerPanel->setVisible(mDisplayChildren);
|
||||
}
|
||||
|
||||
return LLUICtrl::postBuild();
|
||||
}
|
||||
bool LLAccordionCtrlTab::notifyChildren (const LLSD& info)
|
||||
|
||||
bool LLAccordionCtrlTab::notifyChildren (const LLSD& info)
|
||||
{
|
||||
if(info.has("action"))
|
||||
if (info.has("action"))
|
||||
{
|
||||
std::string str_action = info["action"];
|
||||
if(str_action == "store_state")
|
||||
if (str_action == "store_state")
|
||||
{
|
||||
storeOpenCloseState();
|
||||
return true;
|
||||
}
|
||||
if(str_action == "restore_state")
|
||||
|
||||
if (str_action == "restore_state")
|
||||
{
|
||||
restoreOpenCloseState();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return LLUICtrl::notifyChildren(info);
|
||||
}
|
||||
|
||||
S32 LLAccordionCtrlTab::notifyParent(const LLSD& info)
|
||||
{
|
||||
if(info.has("action"))
|
||||
if (info.has("action"))
|
||||
{
|
||||
std::string str_action = info["action"];
|
||||
if(str_action == "size_changes")
|
||||
if (str_action == "size_changes")
|
||||
{
|
||||
//
|
||||
S32 height = info["height"];
|
||||
height = llmax(height,10) + HEADER_HEIGHT + getPaddingTop() + getPaddingBottom();
|
||||
height = llmax(height, 10) + HEADER_HEIGHT + getPaddingTop() + getPaddingBottom();
|
||||
|
||||
mExpandedHeight = height;
|
||||
|
||||
if(isExpanded() && !mSkipChangesOnNotifyParent)
|
||||
if (isExpanded() && !mSkipChangesOnNotifyParent)
|
||||
{
|
||||
LLRect panel_rect = getRect();
|
||||
panel_rect.setLeftTopAndSize( panel_rect.mLeft, panel_rect.mTop, panel_rect.getWidth(), height);
|
||||
|
|
@ -729,12 +739,13 @@ S32 LLAccordionCtrlTab::notifyParent(const LLSD& info)
|
|||
setRect(panel_rect);
|
||||
}
|
||||
|
||||
//LLAccordionCtrl should rearrange accordion tab if one of accordion change its size
|
||||
// LLAccordionCtrl should rearrange accordion tab if one of accordions changed its size
|
||||
if (getParent()) // A parent may not be set if tabs are added dynamically.
|
||||
getParent()->notifyParent(info);
|
||||
return 1;
|
||||
}
|
||||
else if(str_action == "select_prev")
|
||||
|
||||
if (str_action == "select_prev")
|
||||
{
|
||||
showAndFocusHeader();
|
||||
return 1;
|
||||
|
|
@ -772,78 +783,85 @@ S32 LLAccordionCtrlTab::notifyParent(const LLSD& info)
|
|||
|
||||
S32 LLAccordionCtrlTab::notify(const LLSD& info)
|
||||
{
|
||||
if(info.has("action"))
|
||||
if (info.has("action"))
|
||||
{
|
||||
std::string str_action = info["action"];
|
||||
if(str_action == "select_first")
|
||||
if (str_action == "select_first")
|
||||
{
|
||||
showAndFocusHeader();
|
||||
return 1;
|
||||
}
|
||||
else if( str_action == "select_last" )
|
||||
|
||||
if (str_action == "select_last")
|
||||
{
|
||||
if(getDisplayChildren() == false)
|
||||
if (!getDisplayChildren())
|
||||
{
|
||||
showAndFocusHeader();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLView* view = getAccordionView();
|
||||
if(view)
|
||||
view->notify(LLSD().with("action","select_last"));
|
||||
if (view)
|
||||
{
|
||||
view->notify(LLSD().with("action", "select_last"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL LLAccordionCtrlTab::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
||||
{
|
||||
if( !mHeader->hasFocus() )
|
||||
if (!mHeader->hasFocus())
|
||||
return LLUICtrl::handleKey(key, mask, called_from_parent);
|
||||
|
||||
if ( (key == KEY_RETURN )&& mask == MASK_NONE)
|
||||
if ((key == KEY_RETURN) && mask == MASK_NONE)
|
||||
{
|
||||
changeOpenClose(getDisplayChildren());
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( (key == KEY_ADD || key == KEY_RIGHT)&& mask == MASK_NONE)
|
||||
if ((key == KEY_ADD || key == KEY_RIGHT) && mask == MASK_NONE)
|
||||
{
|
||||
if(getDisplayChildren() == false)
|
||||
{
|
||||
changeOpenClose(getDisplayChildren());
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if ( (key == KEY_SUBTRACT || key == KEY_LEFT)&& mask == MASK_NONE)
|
||||
{
|
||||
if(getDisplayChildren() == true)
|
||||
if (!getDisplayChildren())
|
||||
{
|
||||
changeOpenClose(getDisplayChildren());
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if ( key == KEY_DOWN && mask == MASK_NONE)
|
||||
if ((key == KEY_SUBTRACT || key == KEY_LEFT) && mask == MASK_NONE)
|
||||
{
|
||||
//if collapsed go to the next accordion
|
||||
if(getDisplayChildren() == false)
|
||||
//we processing notifyParent so let call parent directly
|
||||
getParent()->notifyParent(LLSD().with("action","select_next"));
|
||||
if (getDisplayChildren())
|
||||
{
|
||||
changeOpenClose(getDisplayChildren());
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (key == KEY_DOWN && mask == MASK_NONE)
|
||||
{
|
||||
// if collapsed go to the next accordion
|
||||
if (!getDisplayChildren())
|
||||
{
|
||||
// we're processing notifyParent so let call parent directly
|
||||
getParent()->notifyParent(LLSD().with("action", "select_next"));
|
||||
}
|
||||
else
|
||||
{
|
||||
getAccordionView()->notify(LLSD().with("action","select_first"));
|
||||
getAccordionView()->notify(LLSD().with("action", "select_first"));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if ( key == KEY_UP && mask == MASK_NONE)
|
||||
if (key == KEY_UP && mask == MASK_NONE)
|
||||
{
|
||||
//go to the previous accordion
|
||||
// go to the previous accordion
|
||||
|
||||
//we processing notifyParent so let call parent directly
|
||||
getParent()->notifyParent(LLSD().with("action","select_prev"));
|
||||
// we're processing notifyParent so let call parent directly
|
||||
getParent()->notifyParent(LLSD().with("action", "select_prev"));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -869,28 +887,29 @@ void LLAccordionCtrlTab::showAndFocusHeader()
|
|||
// accordion tab (assuming that the parent is an LLAccordionCtrl) the calls chain
|
||||
// is shortened and messages from inside the collapsed tabs are avoided.
|
||||
// See STORM-536.
|
||||
getParent()->notifyParent(LLSD().with("scrollToShowRect",screen_rc.getValue()));
|
||||
getParent()->notifyParent(LLSD().with("scrollToShowRect", screen_rc.getValue()));
|
||||
}
|
||||
void LLAccordionCtrlTab::storeOpenCloseState()
|
||||
|
||||
void LLAccordionCtrlTab::storeOpenCloseState()
|
||||
{
|
||||
if(mWasStateStored)
|
||||
if (mWasStateStored)
|
||||
return;
|
||||
mStoredOpenCloseState = getDisplayChildren();
|
||||
mWasStateStored = true;
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::restoreOpenCloseState()
|
||||
void LLAccordionCtrlTab::restoreOpenCloseState()
|
||||
{
|
||||
if(!mWasStateStored)
|
||||
if (!mWasStateStored)
|
||||
return;
|
||||
if(getDisplayChildren() != mStoredOpenCloseState)
|
||||
if (getDisplayChildren() != mStoredOpenCloseState)
|
||||
{
|
||||
changeOpenClose(getDisplayChildren());
|
||||
}
|
||||
mWasStateStored = false;
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::adjustContainerPanel ()
|
||||
void LLAccordionCtrlTab::adjustContainerPanel()
|
||||
{
|
||||
S32 width = getRect().getWidth();
|
||||
S32 height = getRect().getHeight();
|
||||
|
|
@ -907,83 +926,83 @@ void LLAccordionCtrlTab::adjustContainerPanel ()
|
|||
|
||||
void LLAccordionCtrlTab::adjustContainerPanel(const LLRect& child_rect)
|
||||
{
|
||||
if(!mContainerPanel)
|
||||
if (!mContainerPanel)
|
||||
return;
|
||||
|
||||
if(!mFitPanel)
|
||||
if (!mFitPanel)
|
||||
{
|
||||
show_hide_scrollbar(child_rect);
|
||||
updateLayout(child_rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
mContainerPanel->reshape(child_rect.getWidth(),child_rect.getHeight());
|
||||
mContainerPanel->reshape(child_rect.getWidth(), child_rect.getHeight());
|
||||
mContainerPanel->setRect(child_rect);
|
||||
}
|
||||
}
|
||||
|
||||
S32 LLAccordionCtrlTab::getChildViewHeight()
|
||||
{
|
||||
if(!mContainerPanel)
|
||||
if (!mContainerPanel)
|
||||
return 0;
|
||||
return mContainerPanel->getRect().getHeight();
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::show_hide_scrollbar(const LLRect& child_rect)
|
||||
{
|
||||
if(getChildViewHeight() > child_rect.getHeight() )
|
||||
if (getChildViewHeight() > child_rect.getHeight())
|
||||
showScrollbar(child_rect);
|
||||
else
|
||||
hideScrollbar(child_rect);
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::showScrollbar(const LLRect& child_rect)
|
||||
{
|
||||
if(!mContainerPanel || !mScrollbar)
|
||||
if (!mContainerPanel || !mScrollbar)
|
||||
return;
|
||||
bool was_visible = mScrollbar->getVisible();
|
||||
mScrollbar->setVisible(true);
|
||||
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
|
||||
{
|
||||
ctrlSetLeftTopAndSize(mScrollbar,child_rect.getWidth()-scrollbar_size,
|
||||
child_rect.getHeight()-PARENT_BORDER_MARGIN,
|
||||
scrollbar_size,
|
||||
child_rect.getHeight()-2*PARENT_BORDER_MARGIN);
|
||||
}
|
||||
ctrlSetLeftTopAndSize(mScrollbar,
|
||||
child_rect.getWidth() - scrollbar_size,
|
||||
child_rect.getHeight() - PARENT_BORDER_MARGIN,
|
||||
scrollbar_size,
|
||||
child_rect.getHeight() - PARENT_BORDER_MARGIN * 2);
|
||||
|
||||
LLRect orig_rect = mContainerPanel->getRect();
|
||||
|
||||
mScrollbar->setPageSize(child_rect.getHeight());
|
||||
mScrollbar->setDocParams(orig_rect.getHeight(),mScrollbar->getDocPos());
|
||||
mScrollbar->setDocParams(orig_rect.getHeight(), mScrollbar->getDocPos());
|
||||
|
||||
if(was_visible)
|
||||
if (was_visible)
|
||||
{
|
||||
S32 scroll_pos = llmin(mScrollbar->getDocPos(), orig_rect.getHeight() - child_rect.getHeight() - 1);
|
||||
mScrollbar->setDocPos(scroll_pos);
|
||||
}
|
||||
else//shrink child panel
|
||||
else // Shrink child panel
|
||||
{
|
||||
updateLayout(child_rect);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::hideScrollbar( const LLRect& child_rect )
|
||||
void LLAccordionCtrlTab::hideScrollbar(const LLRect& child_rect)
|
||||
{
|
||||
if(!mContainerPanel || !mScrollbar)
|
||||
if (!mContainerPanel || !mScrollbar)
|
||||
return;
|
||||
|
||||
if(mScrollbar->getVisible() == false)
|
||||
if (mScrollbar->getVisible() == FALSE)
|
||||
return;
|
||||
mScrollbar->setVisible(false);
|
||||
|
||||
mScrollbar->setVisible(FALSE);
|
||||
mScrollbar->setDocPos(0);
|
||||
|
||||
//shrink child panel
|
||||
updateLayout(child_rect);
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::onScrollPosChangeCallback(S32, LLScrollbar*)
|
||||
void LLAccordionCtrlTab::onScrollPosChangeCallback(S32, LLScrollbar*)
|
||||
{
|
||||
LLRect child_rect;
|
||||
|
||||
|
|
@ -999,21 +1018,20 @@ void LLAccordionCtrlTab::onScrollPosChangeCallback(S32, LLScrollbar*)
|
|||
updateLayout(child_rect);
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)
|
||||
void LLAccordionCtrlTab::drawChild(const LLRect& root_rect, LLView* child)
|
||||
{
|
||||
if (child && child->getVisible() && child->getRect().isValid())
|
||||
{
|
||||
LLRect screen_rect;
|
||||
localRectToScreen(child->getRect(),&screen_rect);
|
||||
|
||||
if ( root_rect.overlaps(screen_rect) && sDirtyRect.overlaps(screen_rect))
|
||||
localRectToScreen(child->getRect(), &screen_rect);
|
||||
|
||||
if (root_rect.overlaps(screen_rect) && sDirtyRect.overlaps(screen_rect))
|
||||
{
|
||||
gGL.matrixMode(LLRender::MM_MODELVIEW);
|
||||
LLUI::pushMatrix();
|
||||
{
|
||||
LLUI::translate((F32)child->getRect().mLeft, (F32)child->getRect().mBottom);
|
||||
child->draw();
|
||||
|
||||
}
|
||||
LLUI::popMatrix();
|
||||
}
|
||||
|
|
@ -1022,64 +1040,67 @@ void LLAccordionCtrlTab::drawChild(const LLRect& root_rect,LLView* child)
|
|||
|
||||
void LLAccordionCtrlTab::draw()
|
||||
{
|
||||
if(mFitPanel)
|
||||
if (mFitPanel)
|
||||
{
|
||||
LLUICtrl::draw();
|
||||
}
|
||||
else
|
||||
{
|
||||
LLRect root_rect = getRootView()->getRect();
|
||||
drawChild(root_rect,mHeader);
|
||||
drawChild(root_rect,mScrollbar );
|
||||
{
|
||||
LLRect child_rect;
|
||||
LLRect root_rect(getRootView()->getRect());
|
||||
drawChild(root_rect, mHeader);
|
||||
drawChild(root_rect, mScrollbar);
|
||||
|
||||
S32 width = getRect().getWidth();
|
||||
S32 height = getRect().getHeight();
|
||||
LLRect child_rect;
|
||||
|
||||
child_rect.setLeftTopAndSize(
|
||||
getPaddingLeft(),
|
||||
height - getHeaderHeight() - getPaddingTop(),
|
||||
width - getPaddingLeft() - getPaddingRight(),
|
||||
height - getHeaderHeight() - getPaddingTop() - getPaddingBottom() );
|
||||
S32 width = getRect().getWidth();
|
||||
S32 height = getRect().getHeight();
|
||||
|
||||
LLLocalClipRect clip(child_rect);
|
||||
drawChild(root_rect,mContainerPanel);
|
||||
}
|
||||
child_rect.setLeftTopAndSize(
|
||||
getPaddingLeft(),
|
||||
height - getHeaderHeight() - getPaddingTop(),
|
||||
width - getPaddingLeft() - getPaddingRight(),
|
||||
height - getHeaderHeight() - getPaddingTop() - getPaddingBottom());
|
||||
|
||||
LLLocalClipRect clip(child_rect);
|
||||
drawChild(root_rect,mContainerPanel);
|
||||
}
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::updateLayout ( const LLRect& child_rect )
|
||||
void LLAccordionCtrlTab::updateLayout(const LLRect& child_rect)
|
||||
{
|
||||
LLView* child = getAccordionView();
|
||||
if(!mContainerPanel)
|
||||
if (!mContainerPanel)
|
||||
return;
|
||||
|
||||
S32 panel_top = child_rect.getHeight();
|
||||
S32 panel_width = child_rect.getWidth();
|
||||
|
||||
static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
|
||||
if(mScrollbar && mScrollbar->getVisible() != false)
|
||||
static LLUICachedControl<S32> scrollbar_size("UIScrollbarSize", 0);
|
||||
if (mScrollbar && mScrollbar->getVisible())
|
||||
{
|
||||
panel_top+=mScrollbar->getDocPos();
|
||||
panel_width-=scrollbar_size;
|
||||
panel_top += mScrollbar->getDocPos();
|
||||
panel_width -= scrollbar_size;
|
||||
}
|
||||
|
||||
//set sizes for first panels and dragbars
|
||||
// Set sizes for first panels and dragbars
|
||||
LLRect panel_rect = child->getRect();
|
||||
ctrlSetLeftTopAndSize(mContainerPanel,child_rect.mLeft,panel_top,panel_width,panel_rect.getHeight());
|
||||
ctrlSetLeftTopAndSize(mContainerPanel, child_rect.mLeft, panel_top, panel_width, panel_rect.getHeight());
|
||||
}
|
||||
|
||||
void LLAccordionCtrlTab::ctrlSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S32 width, S32 height)
|
||||
{
|
||||
if(!panel)
|
||||
if (!panel)
|
||||
return;
|
||||
LLRect panel_rect = panel->getRect();
|
||||
panel_rect.setLeftTopAndSize( left, top, width, height);
|
||||
panel_rect.setLeftTopAndSize(left, top, width, height);
|
||||
panel->reshape( width, height, 1);
|
||||
panel->setRect(panel_rect);
|
||||
}
|
||||
|
||||
BOOL LLAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask)
|
||||
{
|
||||
//header may be not the first child but we need to process it first
|
||||
if(y >= (getRect().getHeight() - HEADER_HEIGHT - HEADER_HEIGHT/2) )
|
||||
if (y >= (getRect().getHeight() - HEADER_HEIGHT - HEADER_HEIGHT / 2))
|
||||
{
|
||||
//inside tab header
|
||||
//fix for EXT-6619
|
||||
|
|
@ -1088,16 +1109,18 @@ BOOL LLAccordionCtrlTab::handleToolTip(S32 x, S32 y, MASK mask)
|
|||
}
|
||||
return LLUICtrl::handleToolTip(x, y, mask);
|
||||
}
|
||||
BOOL LLAccordionCtrlTab::handleScrollWheel ( S32 x, S32 y, S32 clicks )
|
||||
|
||||
BOOL LLAccordionCtrlTab::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
||||
{
|
||||
if( LLUICtrl::handleScrollWheel(x,y,clicks))
|
||||
if (LLUICtrl::handleScrollWheel(x, y, clicks))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if( mScrollbar && mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) )
|
||||
|
||||
if (mScrollbar && mScrollbar->getVisible() && mScrollbar->handleScrollWheel(0, 0, clicks))
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ public:
|
|||
virtual void setDisplayChildren(bool display);
|
||||
|
||||
// Returns expand/collapse state
|
||||
virtual bool getDisplayChildren() const {return mDisplayChildren;};
|
||||
virtual bool getDisplayChildren() const { return mDisplayChildren; };
|
||||
|
||||
//set LLAccordionCtrlTab panel
|
||||
void setAccordionView(LLView* panel);
|
||||
|
|
|
|||
|
|
@ -1210,7 +1210,7 @@ void LLFlatListView::onFocusReceived()
|
|||
{
|
||||
if (size())
|
||||
{
|
||||
mSelectedItemsBorder->setVisible(TRUE);
|
||||
mSelectedItemsBorder->setVisible(TRUE);
|
||||
}
|
||||
gEditMenuHandler = this;
|
||||
}
|
||||
|
|
@ -1219,7 +1219,7 @@ void LLFlatListView::onFocusLost()
|
|||
{
|
||||
mSelectedItemsBorder->setVisible(FALSE);
|
||||
// Route menu back to the default
|
||||
if( gEditMenuHandler == this )
|
||||
if (gEditMenuHandler == this)
|
||||
{
|
||||
gEditMenuHandler = NULL;
|
||||
}
|
||||
|
|
@ -1228,16 +1228,16 @@ void LLFlatListView::onFocusLost()
|
|||
//virtual
|
||||
S32 LLFlatListView::notify(const LLSD& info)
|
||||
{
|
||||
if(info.has("action"))
|
||||
if (info.has("action"))
|
||||
{
|
||||
std::string str_action = info["action"];
|
||||
if(str_action == "select_first")
|
||||
if (str_action == "select_first")
|
||||
{
|
||||
setFocus(true);
|
||||
selectFirstItem();
|
||||
return 1;
|
||||
}
|
||||
else if(str_action == "select_last")
|
||||
else if (str_action == "select_last")
|
||||
{
|
||||
setFocus(true);
|
||||
selectLastItem();
|
||||
|
|
@ -1250,6 +1250,7 @@ S32 LLFlatListView::notify(const LLSD& info)
|
|||
notifyParentItemsRectChanged();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1261,10 +1262,8 @@ void LLFlatListView::detachItems(std::vector<LLPanel*>& detached_items)
|
|||
detached_items.clear();
|
||||
// Go through items and detach valid items, remove them from items panel
|
||||
// and add to detached_items.
|
||||
for (pairs_iterator_t
|
||||
iter = mItemPairs.begin(),
|
||||
iter_end = mItemPairs.end();
|
||||
iter != iter_end; ++iter)
|
||||
pairs_iterator_t iter = mItemPairs.begin(), iter_end = mItemPairs.end();
|
||||
while (iter != iter_end)
|
||||
{
|
||||
LLPanel* pItem = (*iter)->first;
|
||||
if (1 == pItem->notify(action))
|
||||
|
|
@ -1273,6 +1272,7 @@ void LLFlatListView::detachItems(std::vector<LLPanel*>& detached_items)
|
|||
mItemsPanel->removeChild(pItem);
|
||||
detached_items.push_back(pItem);
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
if (!detached_items.empty())
|
||||
{
|
||||
|
|
@ -1280,13 +1280,12 @@ void LLFlatListView::detachItems(std::vector<LLPanel*>& detached_items)
|
|||
if (detached_items.size() == mItemPairs.size())
|
||||
{
|
||||
// This way will be faster if all items were disconnected
|
||||
for (pairs_iterator_t
|
||||
iter = mItemPairs.begin(),
|
||||
iter_end = mItemPairs.end();
|
||||
iter != iter_end; ++iter)
|
||||
pairs_iterator_t iter = mItemPairs.begin(), iter_end = mItemPairs.end();
|
||||
while (iter != iter_end)
|
||||
{
|
||||
(*iter)->first = NULL;
|
||||
delete *iter;
|
||||
iter++;
|
||||
}
|
||||
mItemPairs.clear();
|
||||
// Also set items panel height to zero.
|
||||
|
|
@ -1299,16 +1298,14 @@ void LLFlatListView::detachItems(std::vector<LLPanel*>& detached_items)
|
|||
}
|
||||
else
|
||||
{
|
||||
for (std::vector<LLPanel*>::const_iterator
|
||||
detached_iter = detached_items.begin(),
|
||||
detached_iter_end = detached_items.end();
|
||||
detached_iter != detached_iter_end; ++detached_iter)
|
||||
std::vector<LLPanel*>::const_iterator
|
||||
detached_iter = detached_items.begin(),
|
||||
detached_iter_end = detached_items.end();
|
||||
while (detached_iter < detached_iter_end)
|
||||
{
|
||||
LLPanel* pDetachedItem = *detached_iter;
|
||||
for (pairs_iterator_t
|
||||
iter = mItemPairs.begin(),
|
||||
iter_end = mItemPairs.end();
|
||||
iter != iter_end; ++iter)
|
||||
pairs_iterator_t iter = mItemPairs.begin(), iter_end = mItemPairs.end();
|
||||
while (iter != iter_end)
|
||||
{
|
||||
item_pair_t* item_pair = *iter;
|
||||
if (item_pair->first == pDetachedItem)
|
||||
|
|
@ -1318,7 +1315,9 @@ void LLFlatListView::detachItems(std::vector<LLPanel*>& detached_items)
|
|||
delete item_pair;
|
||||
break;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
detached_iter++;
|
||||
}
|
||||
rearrangeItems();
|
||||
}
|
||||
|
|
@ -1334,7 +1333,6 @@ LLFlatListViewEx::Params::Params()
|
|||
: no_items_msg("no_items_msg")
|
||||
, no_filtered_items_msg("no_filtered_items_msg")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LLFlatListViewEx::LLFlatListViewEx(const Params& p)
|
||||
|
|
@ -1344,7 +1342,6 @@ LLFlatListViewEx::LLFlatListViewEx(const Params& p)
|
|||
, mForceShowingUnmatchedItems(false)
|
||||
, mHasMatchedItems(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void LLFlatListViewEx::updateNoItemsMessage(const std::string& filter_string)
|
||||
|
|
@ -1364,7 +1361,6 @@ void LLFlatListViewEx::updateNoItemsMessage(const std::string& filter_string)
|
|||
// list does not contain any items at all
|
||||
setNoItemsCommentText(mNoItemsMsg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool LLFlatListViewEx::getForceShowingUnmatchedItems()
|
||||
|
|
@ -1423,12 +1419,10 @@ void LLFlatListViewEx::filterItems()
|
|||
getItems(items);
|
||||
|
||||
mHasMatchedItems = false;
|
||||
for (item_panel_list_t::iterator
|
||||
iter = items.begin(),
|
||||
iter_end = items.end();
|
||||
iter != iter_end; ++iter)
|
||||
item_panel_list_t::iterator iter = items.begin(), iter_end = items.end();
|
||||
while (iter < iter_end)
|
||||
{
|
||||
LLPanel* pItem = (*iter);
|
||||
LLPanel* pItem = *(iter++);
|
||||
updateItemVisibility(pItem, action);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -896,6 +896,24 @@ void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
|
|||
LLPanel::reshape(width, height, called_from_parent);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLFloater::translate(S32 x, S32 y)
|
||||
{
|
||||
LLView::translate(x, y);
|
||||
|
||||
if (!mTranslateWithDependents || mDependents.empty())
|
||||
return;
|
||||
|
||||
for (const LLHandle<LLFloater>& handle : mDependents)
|
||||
{
|
||||
LLFloater* floater = handle.get();
|
||||
if (floater && floater->getSnapTarget() == getHandle())
|
||||
{
|
||||
floater->LLView::translate(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloater::releaseFocus()
|
||||
{
|
||||
LLUI::getInstance()->removePopup(this);
|
||||
|
|
@ -1204,9 +1222,9 @@ BOOL LLFloater::canSnapTo(const LLView* other_view)
|
|||
|
||||
if (other_view != getParent())
|
||||
{
|
||||
const LLFloater* other_floaterp = dynamic_cast<const LLFloater*>(other_view);
|
||||
if (other_floaterp
|
||||
&& other_floaterp->getSnapTarget() == getHandle()
|
||||
const LLFloater* other_floaterp = dynamic_cast<const LLFloater*>(other_view);
|
||||
if (other_floaterp
|
||||
&& other_floaterp->getSnapTarget() == getHandle()
|
||||
&& mDependents.find(other_floaterp->getHandle()) != mDependents.end())
|
||||
{
|
||||
// this is a dependent that is already snapped to us, so don't snap back to it
|
||||
|
|
@ -1639,6 +1657,79 @@ void LLFloater::removeDependentFloater(LLFloater* floaterp)
|
|||
floaterp->mDependeeHandle = LLHandle<LLFloater>();
|
||||
}
|
||||
|
||||
// <FS:Ansariel> Fix floater relocation
|
||||
//void LLFloater::fitWithDependentsOnScreen(const LLRect& left, const LLRect& bottom, const LLRect& right, const LLRect& constraint, S32 min_overlap_pixels)
|
||||
void LLFloater::fitWithDependentsOnScreen(const LLRect& left, const LLRect& bottom, const LLRect& right, const LLRect& chatbar, const LLRect& utilitybar, const LLRect& constraint, S32 min_overlap_pixels)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
LLRect total_rect = getRect();
|
||||
|
||||
for (const LLHandle<LLFloater>& handle : mDependents)
|
||||
{
|
||||
LLFloater* floater = handle.get();
|
||||
if (floater && floater->getSnapTarget() == getHandle())
|
||||
{
|
||||
total_rect.unionWith(floater->getRect());
|
||||
}
|
||||
}
|
||||
|
||||
S32 delta_left = left.notEmpty() ? left.mRight - total_rect.mRight : 0;
|
||||
S32 delta_bottom = bottom.notEmpty() ? bottom.mTop - total_rect.mTop : 0;
|
||||
S32 delta_right = right.notEmpty() ? right.mLeft - total_rect.mLeft : 0;
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
S32 delta_bottom_chatbar = chatbar.notEmpty() ? chatbar.mTop - total_rect.mTop : 0;
|
||||
S32 delta_utility_bar = utilitybar.notEmpty() ? utilitybar.mTop - total_rect.mTop : 0;
|
||||
|
||||
// <FS:Ansariel> Fix floater relocation for vertical toolbars; Only header guarantees that floater can be dragged!
|
||||
S32 header_height = getHeaderHeight();
|
||||
|
||||
// move floater with dependings fully onscreen
|
||||
mTranslateWithDependents = true;
|
||||
if (translateRectIntoRect(total_rect, constraint, min_overlap_pixels))
|
||||
{
|
||||
clearSnapTarget();
|
||||
}
|
||||
// <FS:Ansariel> Fix floater relocation for vertical toolbars; Only header guarantees that floater can be dragged!
|
||||
//else if (delta_left > 0 && total_rect.mTop < left.mTop && total_rect.mBottom > left.mBottom)
|
||||
else if (delta_left > 0 && total_rect.mTop < left.mTop && (total_rect.mTop - header_height) > left.mBottom)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
translate(delta_left, 0);
|
||||
}
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
//else if (delta_bottom > 0 && total_rect.mLeft > bottom.mLeft && total_rect.mRight < bottom.mRight)
|
||||
else if (delta_bottom > 0 && ((total_rect.mLeft > bottom.mLeft && total_rect.mRight < bottom.mRight) // floater completely within toolbar rect
|
||||
|| (total_rect.mLeft > bottom.mLeft && total_rect.mLeft < bottom.mRight && bottom.mRight > constraint.mRight) // floater partially within toolbar rect, toolbar bound to right side
|
||||
|| (delta_bottom_chatbar > 0 && total_rect.mLeft < chatbar.mRight && total_rect.mRight > bottom.mLeft && bottom.mLeft <= chatbar.mRight)) // floater within chatbar and toolbar rect
|
||||
)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
translate(0, delta_bottom);
|
||||
}
|
||||
// <FS:Ansariel> Fix floater relocation for vertical toolbars; Only header guarantees that floater can be dragged!
|
||||
//else if (delta_right < 0 && total_rect.mTop < right.mTop && total_rect.mBottom > right.mBottom)
|
||||
else if (delta_right < 0 && total_rect.mTop < right.mTop && (total_rect.mTop - header_height) > right.mBottom)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
translate(delta_right, 0);
|
||||
}
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
else if (delta_bottom_chatbar > 0 && ((total_rect.mLeft > chatbar.mLeft && total_rect.mRight < chatbar.mRight) // floater completely within chatbar rect
|
||||
|| (total_rect.mRight > chatbar.mLeft && total_rect.mRight < chatbar.mRight && chatbar.mLeft < constraint.mLeft) // floater partially within chatbar rect, chatbar bound to left side
|
||||
|| (delta_bottom > 0 && total_rect.mRight > bottom.mLeft && total_rect.mLeft < chatbar.mRight && bottom.mLeft <= chatbar.mRight)) // floater within chatbar and toolbar rect
|
||||
)
|
||||
{
|
||||
translate(0, delta_bottom_chatbar);
|
||||
}
|
||||
else if (delta_utility_bar > 0 && (total_rect.mLeft > utilitybar.mLeft && total_rect.mRight < utilitybar.mRight))
|
||||
{
|
||||
// Utility bar on legacy skins
|
||||
translate(0, delta_utility_bar);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
mTranslateWithDependents = false;
|
||||
}
|
||||
|
||||
BOOL LLFloater::offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButton index)
|
||||
{
|
||||
if( mButtonsEnabled[index] )
|
||||
|
|
@ -3124,10 +3215,17 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
|
|||
// floater is hosted elsewhere, so ignore
|
||||
return;
|
||||
}
|
||||
|
||||
if (floater->getDependee() &&
|
||||
floater->getDependee() == floater->getSnapTarget().get())
|
||||
{
|
||||
// floater depends on other and snaps to it, so ignore
|
||||
return;
|
||||
}
|
||||
|
||||
LLRect::tCoordType screen_width = getSnapRect().getWidth();
|
||||
LLRect::tCoordType screen_height = getSnapRect().getHeight();
|
||||
|
||||
|
||||
// only automatically resize non-minimized, resizable floaters
|
||||
if( floater->isResizable() && !floater->isMinimized() )
|
||||
{
|
||||
|
|
@ -3169,64 +3267,12 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
|
|||
}
|
||||
}
|
||||
|
||||
const LLRect& left_toolbar_rect = mToolbarLeftRect;
|
||||
const LLRect& bottom_toolbar_rect = mToolbarBottomRect;
|
||||
const LLRect& right_toolbar_rect = mToolbarRightRect;
|
||||
const LLRect& floater_rect = floater->getRect();
|
||||
const LLRect& constraint = snap_in_toolbars ? getSnapRect() : gFloaterView->getRect();
|
||||
S32 min_overlap_pixels = allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX;
|
||||
|
||||
S32 delta_left = left_toolbar_rect.notEmpty() ? left_toolbar_rect.mRight - floater_rect.mRight : 0;
|
||||
S32 delta_bottom = bottom_toolbar_rect.notEmpty() ? bottom_toolbar_rect.mTop - floater_rect.mTop : 0;
|
||||
S32 delta_right = right_toolbar_rect.notEmpty() ? right_toolbar_rect.mLeft - floater_rect.mLeft : 0;
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
S32 delta_bottom_chatbar = mMainChatbarRect.notEmpty() ? mMainChatbarRect.mTop - floater_rect.mTop : 0;
|
||||
S32 delta_utility_bar = mUtilityBarRect.notEmpty() ? mUtilityBarRect.mTop - floater_rect.mTop : 0;
|
||||
|
||||
// <FS:Ansariel> Fix floater relocation for vertical toolbars; Only header guarantees that floater can be dragged!
|
||||
S32 header_height = floater->getHeaderHeight();
|
||||
|
||||
// move window fully onscreen
|
||||
if (floater->translateIntoRect( snap_in_toolbars ? getSnapRect() : gFloaterView->getRect(), allow_partial_outside ? FLOATER_MIN_VISIBLE_PIXELS : S32_MAX ))
|
||||
{
|
||||
floater->clearSnapTarget();
|
||||
}
|
||||
// <FS:Ansariel> Fix floater relocation for vertical toolbars; Only header guarantees that floater can be dragged!
|
||||
//else if (delta_left > 0 && floater_rect.mTop < left_toolbar_rect.mTop && floater_rect.mBottom > left_toolbar_rect.mBottom)
|
||||
else if (delta_left > 0 && floater_rect.mTop < left_toolbar_rect.mTop && (floater_rect.mTop - header_height) > left_toolbar_rect.mBottom)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
floater->translate(delta_left, 0);
|
||||
}
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
//else if (delta_bottom > 0 && floater_rect.mLeft > bottom_toolbar_rect.mLeft && floater_rect.mRight < bottom_toolbar_rect.mRight)
|
||||
else if (delta_bottom > 0 && ((floater_rect.mLeft > bottom_toolbar_rect.mLeft && floater_rect.mRight < bottom_toolbar_rect.mRight) // floater completely within toolbar rect
|
||||
|| (floater_rect.mLeft > bottom_toolbar_rect.mLeft && floater_rect.mLeft < bottom_toolbar_rect.mRight && bottom_toolbar_rect.mRight > gFloaterView->getRect().mRight) // floater partially within toolbar rect, toolbar bound to right side
|
||||
|| (delta_bottom_chatbar > 0 && floater_rect.mLeft < mMainChatbarRect.mRight && floater_rect.mRight > bottom_toolbar_rect.mLeft && bottom_toolbar_rect.mLeft <= mMainChatbarRect.mRight)) // floater within chatbar and toolbar rect
|
||||
)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
floater->translate(0, delta_bottom);
|
||||
}
|
||||
// <FS:Ansariel> Fix floater relocation for vertical toolbars; Only header guarantees that floater can be dragged!
|
||||
//else if (delta_right < 0 && floater_rect.mTop < right_toolbar_rect.mTop && floater_rect.mBottom > right_toolbar_rect.mBottom)
|
||||
else if (delta_right < 0 && floater_rect.mTop < right_toolbar_rect.mTop && (floater_rect.mTop - header_height) > right_toolbar_rect.mBottom)
|
||||
// </FS:Ansariel>
|
||||
{
|
||||
floater->translate(delta_right, 0);
|
||||
}
|
||||
// <FS:Ansariel> Prevent floaters being dragged under main chat bar
|
||||
else if (delta_bottom_chatbar > 0 && ((floater_rect.mLeft > mMainChatbarRect.mLeft && floater_rect.mRight < mMainChatbarRect.mRight) // floater completely within chatbar rect
|
||||
|| (floater_rect.mRight > mMainChatbarRect.mLeft && floater_rect.mRight < mMainChatbarRect.mRight && mMainChatbarRect.mLeft < gFloaterView->getRect().mLeft) // floater partially within chatbar rect, chatbar bound to left side
|
||||
|| (delta_bottom > 0 && floater_rect.mRight > bottom_toolbar_rect.mLeft && floater_rect.mLeft < mMainChatbarRect.mRight && bottom_toolbar_rect.mLeft <= mMainChatbarRect.mRight)) // floater within chatbar and toolbar rect
|
||||
)
|
||||
{
|
||||
floater->translate(0, delta_bottom_chatbar);
|
||||
}
|
||||
else if (delta_utility_bar > 0 && (floater_rect.mLeft > mUtilityBarRect.mLeft && floater_rect.mRight < mUtilityBarRect.mRight))
|
||||
{
|
||||
// Utility bar on legacy skins
|
||||
floater->translate(0, delta_utility_bar);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
// <FS:Ansariel> Fix floater relocation
|
||||
//floater->fitWithDependentsOnScreen(mToolbarLeftRect, mToolbarBottomRect, mToolbarRightRect, constraint, min_overlap_pixels);
|
||||
floater->fitWithDependentsOnScreen(mToolbarLeftRect, mToolbarBottomRect, mToolbarRightRect, mMainChatbarRect, mUtilityBarRect, constraint, min_overlap_pixels);
|
||||
}
|
||||
|
||||
void LLFloaterView::draw()
|
||||
|
|
|
|||
|
|
@ -113,8 +113,6 @@ struct LLCoordFloater : LLCoord<LL_COORD_FLOATER>
|
|||
bool operator!=(const LLCoordFloater& other) const { return !(*this == other); }
|
||||
|
||||
void setFloater(LLFloater& floater);
|
||||
|
||||
|
||||
};
|
||||
|
||||
class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
|
||||
|
|
@ -247,6 +245,7 @@ public:
|
|||
virtual void closeHostedFloater();
|
||||
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
/*virtual*/ void translate(S32 x, S32 y);
|
||||
|
||||
// Release keyboard and mouse focus
|
||||
void releaseFocus();
|
||||
|
|
@ -268,7 +267,11 @@ public:
|
|||
void addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE, BOOL resize = FALSE);
|
||||
void addDependentFloater(LLHandle<LLFloater> dependent_handle, BOOL reposition = TRUE, BOOL resize = FALSE);
|
||||
LLFloater* getDependee() { return (LLFloater*)mDependeeHandle.get(); }
|
||||
void removeDependentFloater(LLFloater* dependent);
|
||||
void removeDependentFloater(LLFloater* dependent);
|
||||
// <FS:Ansariel> Fix floater relocation
|
||||
//void fitWithDependentsOnScreen(const LLRect& left, const LLRect& bottom, const LLRect& right, const LLRect& constraint, S32 min_overlap_pixels);
|
||||
void fitWithDependentsOnScreen(const LLRect& left, const LLRect& bottom, const LLRect& right, const LLRect& chatbar, const LLRect& utilitybar, const LLRect& constraint, S32 min_overlap_pixels);
|
||||
// </FS:Ansariel>
|
||||
BOOL isMinimized() const { return mMinimized; }
|
||||
/// isShown() differs from getVisible() in that isShown() also considers
|
||||
/// isMinimized(). isShown() is true only if visible and not minimized.
|
||||
|
|
@ -531,6 +534,7 @@ private:
|
|||
typedef std::set<LLHandle<LLFloater> > handle_set_t;
|
||||
typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
|
||||
handle_set_t mDependents;
|
||||
bool mTranslateWithDependents { false };
|
||||
|
||||
bool mButtonsEnabled[BUTTON_COUNT];
|
||||
F32 mButtonScale;
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ LLScrollContainer::Params::Params()
|
|||
bg_color("color"),
|
||||
border_visible("border_visible"),
|
||||
hide_scrollbar("hide_scrollbar"),
|
||||
ignore_arrow_keys("ignore_arrow_keys"),
|
||||
min_auto_scroll_rate("min_auto_scroll_rate", 100),
|
||||
max_auto_scroll_rate("max_auto_scroll_rate", 1000),
|
||||
max_auto_scroll_zone("max_auto_scroll_zone", 16),
|
||||
|
|
@ -86,6 +87,7 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)
|
|||
mBackgroundColor(p.bg_color()),
|
||||
mIsOpaque(p.is_opaque),
|
||||
mHideScrollbar(p.hide_scrollbar),
|
||||
mIgnoreArrowKeys(p.ignore_arrow_keys),
|
||||
mReserveScrollCorner(p.reserve_scroll_corner),
|
||||
mMinAutoScrollRate(p.min_auto_scroll_rate),
|
||||
mMaxAutoScrollRate(p.max_auto_scroll_rate),
|
||||
|
|
@ -204,10 +206,29 @@ void LLScrollContainer::reshape(S32 width, S32 height,
|
|||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLScrollContainer::handleKeyHere(KEY key, MASK mask)
|
||||
{
|
||||
if (mIgnoreArrowKeys)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
case KEY_LEFT:
|
||||
case KEY_RIGHT:
|
||||
case KEY_UP:
|
||||
case KEY_DOWN:
|
||||
case KEY_PAGE_UP:
|
||||
case KEY_PAGE_DOWN:
|
||||
case KEY_HOME:
|
||||
case KEY_END:
|
||||
return FALSE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// allow scrolled view to handle keystrokes in case it delegated keyboard focus
|
||||
// to the scroll container.
|
||||
// to the scroll container.
|
||||
// NOTE: this should not recurse indefinitely as handleKeyHere
|
||||
// should not propagate to parent controls, so mScrolledView should *not*
|
||||
// call LLScrollContainer::handleKeyHere in turn
|
||||
|
|
|
|||
|
|
@ -64,7 +64,8 @@ public:
|
|||
Optional<bool> is_opaque,
|
||||
reserve_scroll_corner,
|
||||
border_visible,
|
||||
hide_scrollbar;
|
||||
hide_scrollbar,
|
||||
ignore_arrow_keys;
|
||||
Optional<F32> min_auto_scroll_rate,
|
||||
max_auto_scroll_rate;
|
||||
Optional<U32> max_auto_scroll_zone;
|
||||
|
|
@ -152,6 +153,7 @@ private:
|
|||
F32 mMaxAutoScrollRate;
|
||||
U32 mMaxAutoScrollZone;
|
||||
bool mHideScrollbar;
|
||||
bool mIgnoreArrowKeys;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public:
|
|||
|
||||
|
||||
/*
|
||||
* A set of panels that are displayed in a vertical sequence inside a scroll container.
|
||||
* A set of panels that are displayed in a sequence inside a scroll container.
|
||||
*/
|
||||
class LLScrollingPanelList : public LLUICtrl
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1809,23 +1809,26 @@ LLCoordGL getNeededTranslation(const LLRect& input, const LLRect& constraint, S3
|
|||
const S32 KEEP_ONSCREEN_PIXELS_WIDTH = llmin(min_overlap_pixels, input.getWidth());
|
||||
const S32 KEEP_ONSCREEN_PIXELS_HEIGHT = llmin(min_overlap_pixels, input.getHeight());
|
||||
|
||||
if( input.mRight - KEEP_ONSCREEN_PIXELS_WIDTH < constraint.mLeft )
|
||||
if (KEEP_ONSCREEN_PIXELS_WIDTH <= constraint.getWidth() &&
|
||||
KEEP_ONSCREEN_PIXELS_HEIGHT <= constraint.getHeight())
|
||||
{
|
||||
delta.mX = constraint.mLeft - (input.mRight - KEEP_ONSCREEN_PIXELS_WIDTH);
|
||||
}
|
||||
else if( input.mLeft + KEEP_ONSCREEN_PIXELS_WIDTH > constraint.mRight )
|
||||
{
|
||||
delta.mX = constraint.mRight - (input.mLeft + KEEP_ONSCREEN_PIXELS_WIDTH);
|
||||
}
|
||||
if (input.mRight - KEEP_ONSCREEN_PIXELS_WIDTH < constraint.mLeft)
|
||||
{
|
||||
delta.mX = constraint.mLeft - (input.mRight - KEEP_ONSCREEN_PIXELS_WIDTH);
|
||||
}
|
||||
else if (input.mLeft + KEEP_ONSCREEN_PIXELS_WIDTH > constraint.mRight)
|
||||
{
|
||||
delta.mX = constraint.mRight - (input.mLeft + KEEP_ONSCREEN_PIXELS_WIDTH);
|
||||
}
|
||||
|
||||
if( input.mTop > constraint.mTop )
|
||||
{
|
||||
delta.mY = constraint.mTop - input.mTop;
|
||||
}
|
||||
else
|
||||
if( input.mTop - KEEP_ONSCREEN_PIXELS_HEIGHT < constraint.mBottom )
|
||||
{
|
||||
delta.mY = constraint.mBottom - (input.mTop - KEEP_ONSCREEN_PIXELS_HEIGHT);
|
||||
if (input.mTop > constraint.mTop)
|
||||
{
|
||||
delta.mY = constraint.mTop - input.mTop;
|
||||
}
|
||||
else if (input.mTop - KEEP_ONSCREEN_PIXELS_HEIGHT < constraint.mBottom)
|
||||
{
|
||||
delta.mY = constraint.mBottom - (input.mTop - KEEP_ONSCREEN_PIXELS_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
return delta;
|
||||
|
|
@ -1836,13 +1839,19 @@ LLCoordGL getNeededTranslation(const LLRect& input, const LLRect& constraint, S3
|
|||
// (Why top and left? That's where the drag bars are for floaters.)
|
||||
BOOL LLView::translateIntoRect(const LLRect& constraint, S32 min_overlap_pixels)
|
||||
{
|
||||
LLCoordGL translation = getNeededTranslation(getRect(), constraint, min_overlap_pixels);
|
||||
return translateRectIntoRect(getRect(), constraint, min_overlap_pixels);
|
||||
}
|
||||
|
||||
BOOL LLView::translateRectIntoRect(const LLRect& rect, const LLRect& constraint, S32 min_overlap_pixels)
|
||||
{
|
||||
LLCoordGL translation = getNeededTranslation(rect, constraint, min_overlap_pixels);
|
||||
|
||||
if (translation.mX != 0 || translation.mY != 0)
|
||||
{
|
||||
translate(translation.mX, translation.mY);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -373,6 +373,7 @@ public:
|
|||
virtual void translate( S32 x, S32 y );
|
||||
void setOrigin( S32 x, S32 y ) { mRect.translate( x - mRect.mLeft, y - mRect.mBottom ); }
|
||||
BOOL translateIntoRect( const LLRect& constraint, S32 min_overlap_pixels = S32_MAX);
|
||||
BOOL translateRectIntoRect( const LLRect& rect, const LLRect& constraint, S32 min_overlap_pixels = S32_MAX);
|
||||
BOOL translateIntoRectWithExclusion( const LLRect& inside, const LLRect& exclude, S32 min_overlap_pixels = S32_MAX);
|
||||
void centerWithin(const LLRect& bounds);
|
||||
|
||||
|
|
|
|||
|
|
@ -964,7 +964,8 @@ BOOL FSFloaterIM::postBuild()
|
|||
mEmojiRecentPanel = getChild<LLLayoutPanel>("emoji_recent_layout_panel");
|
||||
mEmojiRecentPanel->setVisible(false);
|
||||
|
||||
mEmojiRecentEmptyText = getChildView("emoji_recent_empty_text");
|
||||
mEmojiRecentEmptyText = getChild<LLTextBox>("emoji_recent_empty_text");
|
||||
mEmojiRecentEmptyText->setToolTip(mEmojiRecentEmptyText->getText());
|
||||
mEmojiRecentEmptyText->setVisible(false);
|
||||
|
||||
mEmojiRecentIconsCtrl = getChild<LLPanelEmojiComplete>("emoji_recent_icons_ctrl");
|
||||
|
|
@ -2473,14 +2474,15 @@ bool FSFloaterIM::applyRectControl()
|
|||
|
||||
void FSFloaterIM::onEmojiRecentPanelToggleBtnClicked(FSFloaterIM* self)
|
||||
{
|
||||
bool restore_focus = (gFocusMgr.getLastKeyboardFocus() == self->mInputEditor);
|
||||
bool show = !self->mEmojiRecentPanel->getVisible();
|
||||
bool restore_focus = !show || (gFocusMgr.getLastKeyboardFocus() == self->mInputEditor);
|
||||
|
||||
BOOL show = !self->mEmojiRecentPanel->getVisible();
|
||||
if (show)
|
||||
{
|
||||
self->initEmojiRecentPanel(!restore_focus);
|
||||
}
|
||||
self->mEmojiRecentPanel->setVisible(show);
|
||||
|
||||
self->mEmojiRecentPanel->setVisible(show ? TRUE : FALSE);
|
||||
self->mEmojiRecentPanelToggleBtn->setImageOverlay(show ? "Arrow_Up" : "Arrow_Down");
|
||||
|
||||
if (restore_focus)
|
||||
|
|
@ -2494,8 +2496,8 @@ void FSFloaterIM::initEmojiRecentPanel(bool moveFocus)
|
|||
std::list<llwchar>& recentlyUsed = LLFloaterEmojiPicker::getRecentlyUsed();
|
||||
if (recentlyUsed.empty())
|
||||
{
|
||||
mEmojiRecentEmptyText->setVisible(true);
|
||||
mEmojiRecentIconsCtrl->setVisible(false);
|
||||
mEmojiRecentEmptyText->setVisible(TRUE);
|
||||
mEmojiRecentIconsCtrl->setVisible(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2505,11 +2507,11 @@ void FSFloaterIM::initEmojiRecentPanel(bool moveFocus)
|
|||
emojis += emoji;
|
||||
}
|
||||
mEmojiRecentIconsCtrl->setEmojis(emojis);
|
||||
mEmojiRecentEmptyText->setVisible(false);
|
||||
mEmojiRecentIconsCtrl->setVisible(true);
|
||||
mEmojiRecentEmptyText->setVisible(FALSE);
|
||||
mEmojiRecentIconsCtrl->setVisible(TRUE);
|
||||
if (moveFocus)
|
||||
{
|
||||
mEmojiRecentIconsCtrl->setFocus(true);
|
||||
mEmojiRecentIconsCtrl->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ private:
|
|||
LLButton* mEmojiRecentPanelToggleBtn;
|
||||
LLButton* mEmojiPickerToggleBtn;
|
||||
LLLayoutPanel* mEmojiRecentPanel;
|
||||
LLView* mEmojiRecentEmptyText;
|
||||
LLTextBox* mEmojiRecentEmptyText;
|
||||
LLPanelEmojiComplete* mEmojiRecentIconsCtrl;
|
||||
|
||||
std::string mSavedTitle;
|
||||
|
|
|
|||
|
|
@ -153,7 +153,8 @@ BOOL FSFloaterNearbyChat::postBuild()
|
|||
mEmojiRecentPanel = getChild<LLLayoutPanel>("emoji_recent_layout_panel");
|
||||
mEmojiRecentPanel->setVisible(false);
|
||||
|
||||
mEmojiRecentEmptyText = getChildView("emoji_recent_empty_text");
|
||||
mEmojiRecentEmptyText = getChild<LLTextBox>("emoji_recent_empty_text");
|
||||
mEmojiRecentEmptyText->setToolTip(mEmojiRecentEmptyText->getText());
|
||||
mEmojiRecentEmptyText->setVisible(false);
|
||||
|
||||
mEmojiRecentIconsCtrl = getChild<LLPanelEmojiComplete>("emoji_recent_icons_ctrl");
|
||||
|
|
@ -971,14 +972,15 @@ void FSFloaterNearbyChat::handleMinimized(bool minimized)
|
|||
|
||||
void FSFloaterNearbyChat::onEmojiRecentPanelToggleBtnClicked(FSFloaterNearbyChat* self)
|
||||
{
|
||||
bool restore_focus = (gFocusMgr.getLastKeyboardFocus() == self->mInputEditor);
|
||||
bool show = !self->mEmojiRecentPanel->getVisible();
|
||||
bool restore_focus = !show || (gFocusMgr.getLastKeyboardFocus() == self->mInputEditor);
|
||||
|
||||
BOOL show = !self->mEmojiRecentPanel->getVisible();
|
||||
if (show)
|
||||
{
|
||||
self->initEmojiRecentPanel(!restore_focus);
|
||||
}
|
||||
self->mEmojiRecentPanel->setVisible(show);
|
||||
|
||||
self->mEmojiRecentPanel->setVisible(show ? TRUE : FALSE);
|
||||
self->mEmojiRecentPanelToggleBtn->setImageOverlay(show ? "Arrow_Up" : "Arrow_Down");
|
||||
|
||||
if (restore_focus)
|
||||
|
|
@ -992,8 +994,8 @@ void FSFloaterNearbyChat::initEmojiRecentPanel(bool moveFocus)
|
|||
std::list<llwchar>& recentlyUsed = LLFloaterEmojiPicker::getRecentlyUsed();
|
||||
if (recentlyUsed.empty())
|
||||
{
|
||||
mEmojiRecentEmptyText->setVisible(true);
|
||||
mEmojiRecentIconsCtrl->setVisible(false);
|
||||
mEmojiRecentEmptyText->setVisible(TRUE);
|
||||
mEmojiRecentIconsCtrl->setVisible(FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1003,11 +1005,11 @@ void FSFloaterNearbyChat::initEmojiRecentPanel(bool moveFocus)
|
|||
emojis += emoji;
|
||||
}
|
||||
mEmojiRecentIconsCtrl->setEmojis(emojis);
|
||||
mEmojiRecentEmptyText->setVisible(false);
|
||||
mEmojiRecentIconsCtrl->setVisible(true);
|
||||
mEmojiRecentEmptyText->setVisible(FALSE);
|
||||
mEmojiRecentIconsCtrl->setVisible(TRUE);
|
||||
if (moveFocus)
|
||||
{
|
||||
mEmojiRecentIconsCtrl->setFocus(true);
|
||||
mEmojiRecentIconsCtrl->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ private:
|
|||
LLButton* mEmojiRecentPanelToggleBtn;
|
||||
LLButton* mEmojiPickerToggleBtn;
|
||||
LLLayoutPanel* mEmojiRecentPanel;
|
||||
LLView* mEmojiRecentEmptyText;
|
||||
LLTextBox* mEmojiRecentEmptyText;
|
||||
LLPanelEmojiComplete* mEmojiRecentIconsCtrl;
|
||||
LLButton* mSendChatButton;
|
||||
LLComboBox* mChatTypeCombo;
|
||||
|
|
|
|||
|
|
@ -281,7 +281,7 @@ void LLFloaterEmojiPicker::show(pick_callback_t pick_callback, close_callback_t
|
|||
}
|
||||
|
||||
LLFloaterEmojiPicker::LLFloaterEmojiPicker(const LLSD& key)
|
||||
: LLFloater(key)
|
||||
: super(key)
|
||||
{
|
||||
loadState();
|
||||
}
|
||||
|
|
@ -403,6 +403,13 @@ void LLFloaterEmojiPicker::moveGroups()
|
|||
mBadge->setRect(rect);
|
||||
}
|
||||
|
||||
void LLFloaterEmojiPicker::showPreview(bool show)
|
||||
{
|
||||
mPreview->setEmoji(nullptr);
|
||||
mDummy->setVisible(show ? FALSE : TRUE);
|
||||
mPreview->setVisible(show ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
void LLFloaterEmojiPicker::fillEmojis(bool fromResize)
|
||||
{
|
||||
mRecentGridWidth = mEmojiScroll->getRect().getWidth();
|
||||
|
|
@ -427,6 +434,9 @@ void LLFloaterEmojiPicker::fillEmojis(bool fromResize)
|
|||
|
||||
mRecentMaxIcons = maxIcons;
|
||||
|
||||
mFocusedIconRow = 0;
|
||||
mFocusedIconCol = 0;
|
||||
mFocusedIcon = nullptr;
|
||||
mHoveredIcon = nullptr;
|
||||
mEmojiGrid->clearPanels();
|
||||
mPreview->setEmoji(nullptr);
|
||||
|
|
@ -573,6 +583,8 @@ void LLFloaterEmojiPicker::onGroupButtonClick(LLUICtrl* ctrl)
|
|||
{
|
||||
if (LLButton* button = dynamic_cast<LLButton*>(ctrl))
|
||||
{
|
||||
mFilter->setFocus(TRUE);
|
||||
|
||||
if (button == mGroupButtons[sSelectedGroupIndex] || button->getToggleState())
|
||||
return;
|
||||
|
||||
|
|
@ -591,8 +603,6 @@ void LLFloaterEmojiPicker::onGroupButtonClick(LLUICtrl* ctrl)
|
|||
rect.mRight = button->getRect().mRight;
|
||||
mBadge->setRect(rect);
|
||||
|
||||
mFilter->setFocus(TRUE);
|
||||
|
||||
fillEmojis();
|
||||
}
|
||||
}
|
||||
|
|
@ -605,15 +615,17 @@ void LLFloaterEmojiPicker::onFilterChanged()
|
|||
|
||||
void LLFloaterEmojiPicker::onGridMouseEnter()
|
||||
{
|
||||
mDummy->setVisible(FALSE);
|
||||
mPreview->setEmoji(nullptr);
|
||||
mPreview->setVisible(TRUE);
|
||||
LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
|
||||
if (focus == mEmojiGrid)
|
||||
{
|
||||
exitArrowMode();
|
||||
}
|
||||
showPreview(true);
|
||||
}
|
||||
|
||||
void LLFloaterEmojiPicker::onGridMouseLeave()
|
||||
{
|
||||
mPreview->setVisible(FALSE);
|
||||
mDummy->setVisible(TRUE);
|
||||
showPreview(false);
|
||||
}
|
||||
|
||||
void LLFloaterEmojiPicker::onGroupButtonMouseEnter(LLUICtrl* ctrl)
|
||||
|
|
@ -636,6 +648,13 @@ void LLFloaterEmojiPicker::onEmojiMouseEnter(LLUICtrl* ctrl)
|
|||
{
|
||||
if (ctrl)
|
||||
{
|
||||
LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
|
||||
if (focus == mEmojiGrid)
|
||||
{
|
||||
exitArrowMode();
|
||||
showPreview(true);
|
||||
}
|
||||
|
||||
if (mHoveredIcon && mHoveredIcon != ctrl)
|
||||
{
|
||||
unselectGridIcon(mHoveredIcon);
|
||||
|
|
@ -685,6 +704,113 @@ void LLFloaterEmojiPicker::onEmojiMouseUp(LLUICtrl* ctrl)
|
|||
}
|
||||
}
|
||||
|
||||
bool LLFloaterEmojiPicker::enterArrowMode()
|
||||
{
|
||||
S32 rowCount = mEmojiGrid->getPanelList().size();
|
||||
if (rowCount)
|
||||
{
|
||||
mFocusedIconRow = -1;
|
||||
mFocusedIconCol = 0;
|
||||
if (moveFocusedIconDown())
|
||||
{
|
||||
showPreview(true);
|
||||
mEmojiScroll->goToTop();
|
||||
mEmojiGrid->setFocus(TRUE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLFloaterEmojiPicker::exitArrowMode()
|
||||
{
|
||||
if (mFocusedIcon)
|
||||
{
|
||||
unselectGridIcon(mFocusedIcon);
|
||||
mFocusedIcon = nullptr;
|
||||
}
|
||||
|
||||
showPreview(false);
|
||||
mEmojiScroll->goToTop();
|
||||
mFocusedIconRow = mFocusedIconCol = 0;
|
||||
mFilter->setFocus(TRUE);
|
||||
}
|
||||
|
||||
void LLFloaterEmojiPicker::selectFocusedIcon()
|
||||
{
|
||||
if (mHoveredIcon)
|
||||
{
|
||||
unselectGridIcon(mHoveredIcon);
|
||||
}
|
||||
|
||||
if (mFocusedIcon)
|
||||
{
|
||||
unselectGridIcon(mFocusedIcon);
|
||||
}
|
||||
|
||||
// Both mFocusedIconRow and mFocusedIconCol should be already verified
|
||||
LLEmojiGridRow* row = (LLEmojiGridRow*)mEmojiGrid->getPanelList()[mFocusedIconRow];
|
||||
mFocusedIcon = row->mList->getPanelList()[mFocusedIconCol];
|
||||
selectGridIcon(mFocusedIcon);
|
||||
}
|
||||
|
||||
bool LLFloaterEmojiPicker::moveFocusedIconUp()
|
||||
{
|
||||
for (S32 i = mFocusedIconRow - 1; i >= 0; --i)
|
||||
{
|
||||
LLScrollingPanel* panel = mEmojiGrid->getPanelList()[i];
|
||||
LLEmojiGridRow* row = dynamic_cast<LLEmojiGridRow*>(panel);
|
||||
if (row && row->mList->getPanelList().size() > mFocusedIconCol)
|
||||
{
|
||||
mEmojiScroll->scrollToShowRect(row->getBoundingRect());
|
||||
mFocusedIconRow = i;
|
||||
selectFocusedIcon();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLFloaterEmojiPicker::moveFocusedIconDown()
|
||||
{
|
||||
S32 rowCount = mEmojiGrid->getPanelList().size();
|
||||
for (S32 i = mFocusedIconRow + 1; i < rowCount; ++i)
|
||||
{
|
||||
LLScrollingPanel* panel = mEmojiGrid->getPanelList()[i];
|
||||
LLEmojiGridRow* row = dynamic_cast<LLEmojiGridRow*>(panel);
|
||||
if (row && row->mList->getPanelList().size() > mFocusedIconCol)
|
||||
{
|
||||
mEmojiScroll->scrollToShowRect(row->getBoundingRect());
|
||||
mFocusedIconRow = i;
|
||||
selectFocusedIcon();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLFloaterEmojiPicker::moveFocusedIconLeft()
|
||||
{
|
||||
if (mFocusedIconCol <= 0)
|
||||
return false;
|
||||
|
||||
mFocusedIconCol--;
|
||||
selectFocusedIcon();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLFloaterEmojiPicker::moveFocusedIconRight()
|
||||
{
|
||||
LLEmojiGridRow* row = (LLEmojiGridRow*)mEmojiGrid->getPanelList()[mFocusedIconRow];
|
||||
S32 colCount = row->mList->getPanelList().size();
|
||||
if (mFocusedIconCol >= colCount - 1)
|
||||
return false;
|
||||
|
||||
mFocusedIconCol++;
|
||||
selectFocusedIcon();
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLFloaterEmojiPicker::selectGridIcon(LLUICtrl* ctrl)
|
||||
{
|
||||
if (LLEmojiGridIcon* icon = dynamic_cast<LLEmojiGridIcon*>(ctrl))
|
||||
|
|
@ -703,6 +829,64 @@ void LLFloaterEmojiPicker::unselectGridIcon(LLUICtrl* ctrl)
|
|||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLFloaterEmojiPicker::handleKey(KEY key, MASK mask, BOOL called_from_parent)
|
||||
{
|
||||
if (mask == MASK_NONE)
|
||||
{
|
||||
LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
|
||||
if (focus == mEmojiGrid)
|
||||
{
|
||||
if (key == KEY_RETURN)
|
||||
{
|
||||
if (mFocusedIcon)
|
||||
{
|
||||
onEmojiMouseDown(mFocusedIcon);
|
||||
onEmojiMouseUp(mFocusedIcon);
|
||||
closeFloater();
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else if (key == KEY_TAB)
|
||||
{
|
||||
exitArrowMode();
|
||||
return TRUE;
|
||||
}
|
||||
else if (key == KEY_UP)
|
||||
{
|
||||
if (!moveFocusedIconUp())
|
||||
exitArrowMode();
|
||||
return TRUE;
|
||||
}
|
||||
else if (key == KEY_DOWN)
|
||||
{
|
||||
if (moveFocusedIconDown())
|
||||
return TRUE;
|
||||
}
|
||||
else if (key == KEY_LEFT)
|
||||
{
|
||||
if (moveFocusedIconLeft())
|
||||
return TRUE;
|
||||
}
|
||||
else if (key == KEY_RIGHT)
|
||||
{
|
||||
if (moveFocusedIconRight())
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
else // if (focus != mEmojiGrid)
|
||||
{
|
||||
if (key == KEY_DOWN)
|
||||
{
|
||||
if (enterArrowMode())
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return super::handleKey(key, mask, called_from_parent);
|
||||
}
|
||||
|
||||
// virtual
|
||||
BOOL LLFloaterEmojiPicker::handleKeyHere(KEY key, MASK mask)
|
||||
{
|
||||
|
|
@ -716,14 +900,14 @@ BOOL LLFloaterEmojiPicker::handleKeyHere(KEY key, MASK mask)
|
|||
}
|
||||
}
|
||||
|
||||
return LLFloater::handleKeyHere(key, mask);
|
||||
return super::handleKeyHere(key, mask);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLFloaterEmojiPicker::closeFloater(bool app_quitting)
|
||||
{
|
||||
saveState();
|
||||
LLFloater::closeFloater(app_quitting);
|
||||
super::closeFloater(app_quitting);
|
||||
if (mFloaterCloseCallback)
|
||||
{
|
||||
mFloaterCloseCallback();
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public:
|
|||
private:
|
||||
void fillGroups();
|
||||
void moveGroups();
|
||||
void showPreview(bool show);
|
||||
void fillEmojis(bool fromResize = false);
|
||||
|
||||
void onGroupButtonClick(LLUICtrl* ctrl);
|
||||
|
|
@ -84,9 +85,18 @@ private:
|
|||
void onEmojiMouseDown(LLUICtrl* ctrl);
|
||||
void onEmojiMouseUp(LLUICtrl* ctrl);
|
||||
|
||||
bool enterArrowMode();
|
||||
void exitArrowMode();
|
||||
void selectFocusedIcon();
|
||||
bool moveFocusedIconUp();
|
||||
bool moveFocusedIconDown();
|
||||
bool moveFocusedIconLeft();
|
||||
bool moveFocusedIconRight();
|
||||
|
||||
void selectGridIcon(LLUICtrl* ctrl);
|
||||
void unselectGridIcon(LLUICtrl* ctrl);
|
||||
|
||||
virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent) override;
|
||||
virtual BOOL handleKeyHere(KEY key, MASK mask) override;
|
||||
|
||||
class LLPanel* mGroups { nullptr };
|
||||
|
|
@ -105,6 +115,9 @@ private:
|
|||
S32 mRecentBadgeWidth { 0 };
|
||||
S32 mRecentGridWidth { 0 };
|
||||
S32 mRecentMaxIcons { 0 };
|
||||
S32 mFocusedIconRow { 0 };
|
||||
S32 mFocusedIconCol { 0 };
|
||||
LLUICtrl* mFocusedIcon { nullptr };
|
||||
LLUICtrl* mHoveredIcon { nullptr };
|
||||
|
||||
// <FS:Ansariel> Live-update recently used emojis
|
||||
|
|
|
|||
|
|
@ -266,7 +266,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
|
|||
mEmojiRecentPanel = getChild<LLLayoutPanel>("emoji_recent_layout_panel");
|
||||
mEmojiRecentPanel->setVisible(false);
|
||||
|
||||
mEmojiRecentEmptyText = getChildView("emoji_recent_empty_text");
|
||||
mEmojiRecentEmptyText = getChild<LLTextBox>("emoji_recent_empty_text");
|
||||
mEmojiRecentEmptyText->setToolTip(mEmojiRecentEmptyText->getText());
|
||||
mEmojiRecentEmptyText->setVisible(false);
|
||||
|
||||
mEmojiRecentIconsCtrl = getChild<LLPanelEmojiComplete>("emoji_recent_icons_ctrl");
|
||||
|
|
@ -274,7 +275,7 @@ BOOL LLFloaterIMSessionTab::postBuild()
|
|||
mEmojiRecentIconsCtrl->setVisible(false);
|
||||
|
||||
mEmojiPickerToggleBtn = getChild<LLButton>("emoji_picker_toggle_btn");
|
||||
mEmojiPickerToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnClicked(this); });
|
||||
mEmojiPickerToggleBtn->setClickedCallback([this](LLUICtrl*, const LLSD&) { onEmojiPickerToggleBtnClicked(); });
|
||||
|
||||
mGearBtn = getChild<LLButton>("gear_btn");
|
||||
mAddBtn = getChild<LLButton>("add_btn");
|
||||
|
|
@ -455,14 +456,15 @@ void LLFloaterIMSessionTab::onInputEditorClicked()
|
|||
|
||||
void LLFloaterIMSessionTab::onEmojiRecentPanelToggleBtnClicked(LLFloaterIMSessionTab* self)
|
||||
{
|
||||
bool restore_focus = (gFocusMgr.getLastKeyboardFocus() == self->mInputEditor);
|
||||
bool show = !self->mEmojiRecentPanel->getVisible();
|
||||
bool restore_focus = !show || (gFocusMgr.getLastKeyboardFocus() == self->mInputEditor);
|
||||
|
||||
BOOL show = !self->mEmojiRecentPanel->getVisible();
|
||||
if (show)
|
||||
{
|
||||
if (show)
|
||||
{
|
||||
self->initEmojiRecentPanel(!restore_focus);
|
||||
}
|
||||
self->mEmojiRecentPanel->setVisible(show);
|
||||
}
|
||||
|
||||
self->mEmojiRecentPanel->setVisible(show ? TRUE : FALSE);
|
||||
|
||||
if (restore_focus)
|
||||
{
|
||||
|
|
@ -470,18 +472,18 @@ void LLFloaterIMSessionTab::onEmojiRecentPanelToggleBtnClicked(LLFloaterIMSessio
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterIMSessionTab::onEmojiPickerToggleBtnClicked(LLFloaterIMSessionTab* self)
|
||||
void LLFloaterIMSessionTab::onEmojiPickerToggleBtnClicked()
|
||||
{
|
||||
if (LLFloaterEmojiPicker* picker = LLFloaterEmojiPicker::getInstance())
|
||||
{
|
||||
if (!picker->isShown())
|
||||
{
|
||||
picker->show(
|
||||
[self](llwchar emoji) { self->onEmojiPicked(emoji); },
|
||||
[self]() { self->onEmojiPickerClosed(); });
|
||||
if (LLFloater* root_floater = gFloaterView->getParentFloater(self))
|
||||
[](llwchar emoji) { onEmojiPicked(emoji); },
|
||||
[]() { onEmojiPickerClosed(); });
|
||||
if (LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance())
|
||||
{
|
||||
root_floater->addDependentFloater(picker, TRUE, TRUE);
|
||||
im_box->addDependentFloater(picker, TRUE, TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -496,11 +498,11 @@ void LLFloaterIMSessionTab::initEmojiRecentPanel(bool moveFocus)
|
|||
std::list<llwchar>& recentlyUsed = LLFloaterEmojiPicker::getRecentlyUsed();
|
||||
if (recentlyUsed.empty())
|
||||
{
|
||||
mEmojiRecentEmptyText->setVisible(true);
|
||||
mEmojiRecentIconsCtrl->setVisible(false);
|
||||
mEmojiRecentEmptyText->setVisible(TRUE);
|
||||
mEmojiRecentIconsCtrl->setVisible(FALSE);
|
||||
if (moveFocus)
|
||||
{
|
||||
mEmojiPickerToggleBtn->setFocus(true);
|
||||
mEmojiPickerToggleBtn->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -511,11 +513,11 @@ void LLFloaterIMSessionTab::initEmojiRecentPanel(bool moveFocus)
|
|||
emojis += emoji;
|
||||
}
|
||||
mEmojiRecentIconsCtrl->setEmojis(emojis);
|
||||
mEmojiRecentEmptyText->setVisible(false);
|
||||
mEmojiRecentIconsCtrl->setVisible(true);
|
||||
mEmojiRecentEmptyText->setVisible(FALSE);
|
||||
mEmojiRecentIconsCtrl->setVisible(TRUE);
|
||||
if (moveFocus)
|
||||
{
|
||||
mEmojiRecentIconsCtrl->setFocus(true);
|
||||
mEmojiRecentIconsCtrl->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -534,15 +536,29 @@ void LLFloaterIMSessionTab::onRecentEmojiPicked(const LLSD& value)
|
|||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterIMSessionTab::onEmojiPicked(llwchar emoji)
|
||||
{
|
||||
mInputEditor->insertEmoji(emoji);
|
||||
mInputEditor->setFocus(TRUE);
|
||||
if (LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance())
|
||||
{
|
||||
if (LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(im_box->getSelectedSession()))
|
||||
{
|
||||
session_floater->mInputEditor->insertEmoji(emoji);
|
||||
session_floater->mInputEditor->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterIMSessionTab::onEmojiPickerClosed()
|
||||
{
|
||||
mInputEditor->setFocus(TRUE);
|
||||
if (LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance())
|
||||
{
|
||||
if (LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(im_box->getSelectedSession()))
|
||||
{
|
||||
session_floater->mInputEditor->setFocus(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterIMSessionTab::closeFloater(bool app_quitting)
|
||||
|
|
|
|||
|
|
@ -174,7 +174,7 @@ protected:
|
|||
LLLayoutPanel* mToolbarPanel;
|
||||
LLLayoutPanel* mInputButtonPanel;
|
||||
LLLayoutPanel* mEmojiRecentPanel;
|
||||
LLView* mEmojiRecentEmptyText;
|
||||
LLTextBox* mEmojiRecentEmptyText;
|
||||
LLPanelEmojiComplete* mEmojiRecentIconsCtrl;
|
||||
LLParticipantList* getParticipantList();
|
||||
conversations_widgets_map mConversationsWidgets;
|
||||
|
|
@ -218,11 +218,11 @@ private:
|
|||
void onInputEditorClicked();
|
||||
|
||||
static void onEmojiRecentPanelToggleBtnClicked(LLFloaterIMSessionTab* self);
|
||||
static void onEmojiPickerToggleBtnClicked(LLFloaterIMSessionTab* self);
|
||||
static void onEmojiPickerToggleBtnClicked();
|
||||
void initEmojiRecentPanel(bool moveFocus);
|
||||
void onRecentEmojiPicked(const LLSD& value);
|
||||
void onEmojiPicked(llwchar emoji);
|
||||
void onEmojiPickerClosed();
|
||||
static void onEmojiPicked(llwchar emoji);
|
||||
static void onEmojiPickerClosed();
|
||||
|
||||
bool checkIfTornOff();
|
||||
bool mIsHostAttached;
|
||||
|
|
|
|||
|
|
@ -285,7 +285,14 @@ void LLPanelEmojiComplete::onCommit()
|
|||
void LLPanelEmojiComplete::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
{
|
||||
LLUICtrl::reshape(width, height, called_from_parent);
|
||||
updateConstraints();
|
||||
if (mAutoSize)
|
||||
{
|
||||
updateConstraints();
|
||||
}
|
||||
else
|
||||
{
|
||||
onEmojisChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelEmojiComplete::setEmojis(const LLWString& emojis)
|
||||
|
|
@ -373,7 +380,9 @@ void LLPanelEmojiComplete::onEmojisChanged()
|
|||
}
|
||||
else
|
||||
{
|
||||
mVisibleEmojis = mVertical ? getRect().getHeight() / mEmojiHeight : getRect().getWidth() / mEmojiWidth;
|
||||
mVisibleEmojis = mVertical ?
|
||||
mEmojiHeight ? getRect().getHeight() / mEmojiHeight : 0 :
|
||||
mEmojiWidth ? getRect().getWidth() / mEmojiWidth : 0;
|
||||
}
|
||||
|
||||
updateConstraints();
|
||||
|
|
|
|||
|
|
@ -3510,6 +3510,7 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
|
|||
case KEY_PAGE_UP:
|
||||
case KEY_PAGE_DOWN:
|
||||
case KEY_HOME:
|
||||
case KEY_END:
|
||||
// when chatbar is empty or ArrowKeysAlwaysMove set,
|
||||
// pass arrow keys on to avatar...
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
name="EmojiGridContainer"
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
ignore_arrow_keys="true"
|
||||
top="50"
|
||||
left="0"
|
||||
height="309"
|
||||
|
|
|
|||
Loading…
Reference in New Issue