Newer
Older
btn_rect.setLeftTopAndSize(tabcntrv_pad + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor
(getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + tabcntrv_pad) * getTabCount()),
Steven Bennetts
committed
mMinTabWidth,
BTN_HEIGHT);
}
else if( getTabPosition() == LLTabContainer::TOP )
{
btn_rect.setLeftTopAndSize( 0, getRect().getHeight() - getTopBorderHeight() + tab_fudge, button_width, mTabHeight);
tab_img = mMiddleTabParams.tab_top_image_unselected;
tab_selected_img = mMiddleTabParams.tab_top_image_selected;
btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, mTabHeight);
tab_img = mMiddleTabParams.tab_bottom_image_unselected;
tab_selected_img = mMiddleTabParams.tab_bottom_image_selected;
Steven Bennetts
committed
LLTextBox* textbox = NULL;
LLButton* btn = NULL;
Ychebotarev ProductEngine
committed
LLCustomButtonIconCtrl::Params custom_btn_params;
{
custom_btn_params.icon_ctrl_pad(mTabIconCtrlPad);
}
LLButton::Params normal_btn_params;
Steven Bennetts
committed
btn_rect.translate(0, -6); // *TODO: make configurable
LLTextBox::Params params;
params.name(trimmed_label);
params.rect(btn_rect);
James Cook
committed
params.initial_value(trimmed_label);
textbox = LLUICtrlFactory::create<LLTextBox> (params);
Steven Bennetts
committed
LLButton::Params p;
p.name("placeholder");
btn = LLUICtrlFactory::create<LLButton>(p);
LLButton::Params& p = (mCustomIconCtrlUsed ? custom_btn_params : normal_btn_params);
p.rect(btn_rect);
p.font(mFont);
p.font_halign = mFontHalign;
p.label(trimmed_label);
p.click_callback.function(boost::bind(&LLTabContainer::onTabBtn, this, _2, child));
if (indent)
{
p.pad_left(indent);
}
p.pad_bottom( mLabelPadBottom );
p.scale_image(true);
p.tab_stop(false);
p.label_shadow(false);
p.follows.flags = FOLLOWS_LEFT;
Steven Bennetts
committed
if (mIsVertical)
p.name(std::string("vert tab button"));
p.image_unselected(mMiddleTabParams.tab_left_image_unselected);
p.image_selected(mMiddleTabParams.tab_left_image_selected);
p.follows.flags = p.follows.flags() | FOLLOWS_TOP;
p.name(std::string(child->getName()) + " tab");
p.visible(false);
p.image_unselected(tab_img);
p.image_selected(tab_selected_img);
p.follows.flags = p.follows.flags() | (getTabPosition() == TOP ? FOLLOWS_TOP : FOLLOWS_BOTTOM);
Steven Bennetts
committed
// Try to squeeze in a bit more text
p.pad_left( mLabelPadLeft );
p.pad_right(2);
}
// *TODO : It seems wrong not to use p in both cases considering the way p is initialized
if (mCustomIconCtrlUsed)
{
btn = LLUICtrlFactory::create<LLCustomButtonIconCtrl>(custom_btn_params);
}
else
{
btn = LLUICtrlFactory::create<LLButton>(p);
Steven Bennetts
committed
}
LLTabTuple* tuple = new LLTabTuple( this, child, btn, textbox );
Steven Bennetts
committed
insertTuple( tuple, insertion_point );
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
// if new tab was added as a first or last tab, update button image
// and update button image of any tab it may have affected
if (tuple == mTabList.front())
{
update_images(tuple, mFirstTabParams, getTabPosition());
if (mTabList.size() == 2)
{
update_images(mTabList[1], mLastTabParams, getTabPosition());
}
else if (mTabList.size() > 2)
{
update_images(mTabList[1], mMiddleTabParams, getTabPosition());
}
}
else if (tuple == mTabList.back())
{
update_images(tuple, mLastTabParams, getTabPosition());
if (mTabList.size() > 2)
{
update_images(mTabList[mTabList.size()-2], mMiddleTabParams, getTabPosition());
}
}
//Don't add button and textbox if tab buttons are invisible(EXT - 576)
if (!getTabsHidden())
Steven Bennetts
committed
{
if (textbox)
{
addChild( textbox, 0 );
}
if (btn)
{
addChild( btn, 0 );
}
Steven Bennetts
committed
if (child)
{
LLUICtrl::addChild(child, 1);
Steven Bennetts
committed
}
sendChildToFront(mPrevArrowBtn);
sendChildToFront(mNextArrowBtn);
sendChildToFront(mJumpPrevArrowBtn);
sendChildToFront(mJumpNextArrowBtn);
Steven Bennetts
committed
Steven Bennetts
committed
updateMaxScrollPos();
}
void LLTabContainer::addPlaceholder(LLPanel* child, const std::string& label)
Steven Bennetts
committed
{
addTabPanel(TabPanelParams().panel(child).label(label).is_placeholder(true));
}
void LLTabContainer::removeTabPanel(LLPanel* child)
{
static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
Steven Bennetts
committed
if (mIsVertical)
{
// Fix-up button sizes
S32 tab_count = 0;
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
LLTabTuple* tuple = *iter;
LLRect rect;
rect.setLeftTopAndSize(tabcntrv_pad + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor
(getRect().getHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + tabcntrv_pad) * (tab_count)),
Steven Bennetts
committed
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
mMinTabWidth,
BTN_HEIGHT);
if (tuple->mPlaceholderText)
{
tuple->mPlaceholderText->setRect(rect);
}
else
{
tuple->mButton->setRect(rect);
}
tab_count++;
}
}
else
{
// Adjust the total tab width.
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
LLTabTuple* tuple = *iter;
if( tuple->mTabPanel == child )
{
mTotalTabWidth -= tuple->mButton->getRect().getWidth();
break;
}
}
}
BOOL has_focus = gFocusMgr.childHasKeyboardFocus(this);
// If the tab being deleted is the selected one, select a different tab.
for(std::vector<LLTabTuple*>::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
LLTabTuple* tuple = *iter;
if( tuple->mTabPanel == child )
{
// update tab button images if removing the first or last tab
if ((tuple == mTabList.front()) && (mTabList.size() > 1))
{
update_images(mTabList[1], mFirstTabParams, getTabPosition());
}
else if ((tuple == mTabList.back()) && (mTabList.size() > 2))
{
update_images(mTabList[mTabList.size()-2], mLastTabParams, getTabPosition());
}
Seth ProductEngine
committed
if (!getTabsHidden())
{
// We need to remove tab buttons only if the tabs are not hidden.
removeChild( tuple->mButton );
}
Steven Bennetts
committed
delete tuple->mButton;
Merov Linden
committed
tuple->mButton = NULL;
Steven Bennetts
committed
removeChild( tuple->mTabPanel );
// delete tuple->mTabPanel;
Merov Linden
committed
tuple->mTabPanel = NULL;
Steven Bennetts
committed
mTabList.erase( iter );
delete tuple;
Steven Bennetts
committed
// make sure we don't have more locked tabs than we have tabs
mLockedTabCount = llmin(getTabCount(), mLockedTabCount);
if (mCurrentTabIdx >= (S32)mTabList.size())
{
mCurrentTabIdx = mTabList.size()-1;
}
selectTab(mCurrentTabIdx);
if (has_focus)
{
LLPanel* panelp = getPanelByIndex(mCurrentTabIdx);
if (panelp)
{
panelp->setFocus(TRUE);
}
}
updateMaxScrollPos();
Steven Bennetts
committed
void LLTabContainer::lockTabs(S32 num_tabs)
Steven Bennetts
committed
// count current tabs or use supplied value and ensure no new tabs get
// inserted between them
mLockedTabCount = num_tabs > 0 ? llmin(getTabCount(), num_tabs) : getTabCount();
}
void LLTabContainer::unlockTabs()
{
mLockedTabCount = 0;
}
void LLTabContainer::enableTabButton(S32 which, BOOL enable)
{
if (which >= 0 && which < (S32)mTabList.size())
Steven Bennetts
committed
mTabList[which]->mButton->setEnabled(enable);
Merov Linden
committed
// Stop the DaD timer as it might run forever
// enableTabButton() is typically called on refresh and draw when anything changed
// in the tab container so it's a good time to reset that.
mDragAndDropDelayTimer.stop();
Steven Bennetts
committed
void LLTabContainer::deleteAllTabs()
{
// Remove all the tab buttons and delete them. Also, unlink all the child panels.
for(std::vector<LLTabTuple*>::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
LLTabTuple* tuple = *iter;
Steven Bennetts
committed
removeChild( tuple->mButton );
delete tuple->mButton;
Merov Linden
committed
tuple->mButton = NULL;
Steven Bennetts
committed
removeChild( tuple->mTabPanel );
// delete tuple->mTabPanel;
Merov Linden
committed
tuple->mTabPanel = NULL;
Steven Bennetts
committed
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
}
// Actually delete the tuples themselves
std::for_each(mTabList.begin(), mTabList.end(), DeletePointer());
mTabList.clear();
// And there isn't a current tab any more
mCurrentTabIdx = -1;
}
LLPanel* LLTabContainer::getCurrentPanel()
{
if (mCurrentTabIdx >= 0 && mCurrentTabIdx < (S32) mTabList.size())
{
return mTabList[mCurrentTabIdx]->mTabPanel;
}
return NULL;
}
S32 LLTabContainer::getCurrentPanelIndex()
{
return mCurrentTabIdx;
}
S32 LLTabContainer::getTabCount()
Steven Bennetts
committed
return mTabList.size();
}
Steven Bennetts
committed
LLPanel* LLTabContainer::getPanelByIndex(S32 index)
{
if (index >= 0 && index < (S32)mTabList.size())
Steven Bennetts
committed
return mTabList[index]->mTabPanel;
}
return NULL;
}
Steven Bennetts
committed
S32 LLTabContainer::getIndexForPanel(LLPanel* panel)
{
for (S32 index = 0; index < (S32)mTabList.size(); index++)
{
if (mTabList[index]->mTabPanel == panel)
Steven Bennetts
committed
return index;
Steven Bennetts
committed
return -1;
}
S32 LLTabContainer::getPanelIndexByTitle(const std::string& title)
Steven Bennetts
committed
{
for (S32 index = 0 ; index < (S32)mTabList.size(); index++)
Steven Bennetts
committed
if (title == mTabList[index]->mButton->getLabelSelected())
{
return index;
}
Steven Bennetts
committed
return -1;
LLPanel* LLTabContainer::getPanelByName(const std::string& name)
Steven Bennetts
committed
for (S32 index = 0 ; index < (S32)mTabList.size(); index++)
Steven Bennetts
committed
LLPanel *panel = mTabList[index]->mTabPanel;
if (name == panel->getName())
Steven Bennetts
committed
return panel;
Steven Bennetts
committed
return NULL;
}
// Change the name of the button for the current tab.
void LLTabContainer::setCurrentTabName(const std::string& name)
Steven Bennetts
committed
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
{
// Might not have a tab selected
if (mCurrentTabIdx < 0) return;
mTabList[mCurrentTabIdx]->mButton->setLabelSelected(name);
mTabList[mCurrentTabIdx]->mButton->setLabelUnselected(name);
}
void LLTabContainer::selectFirstTab()
{
selectTab( 0 );
}
void LLTabContainer::selectLastTab()
{
selectTab( mTabList.size()-1 );
}
void LLTabContainer::selectNextTab()
{
BOOL tab_has_focus = FALSE;
if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus())
{
tab_has_focus = TRUE;
}
S32 idx = mCurrentTabIdx+1;
if (idx >= (S32)mTabList.size())
idx = 0;
while (!selectTab(idx) && idx != mCurrentTabIdx)
{
idx = (idx + 1 ) % (S32)mTabList.size();
}
if (tab_has_focus)
{
mTabList[idx]->mButton->setFocus(TRUE);
}
}
void LLTabContainer::selectPrevTab()
{
BOOL tab_has_focus = FALSE;
if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus())
{
tab_has_focus = TRUE;
}
S32 idx = mCurrentTabIdx-1;
if (idx < 0)
idx = mTabList.size()-1;
while (!selectTab(idx) && idx != mCurrentTabIdx)
{
idx = idx - 1;
if (idx < 0)
idx = mTabList.size()-1;
}
if (tab_has_focus)
{
mTabList[idx]->mButton->setFocus(TRUE);
}
}
Steven Bennetts
committed
BOOL LLTabContainer::selectTabPanel(LLPanel* child)
Steven Bennetts
committed
S32 idx = 0;
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
LLTabTuple* tuple = *iter;
if( tuple->mTabPanel == child )
{
return selectTab( idx );
}
idx++;
}
return FALSE;
}
BOOL LLTabContainer::selectTab(S32 which)
{
if (which >= getTabCount() || which < 0)
return FALSE;
Steven Bennetts
committed
LLTabTuple* selected_tuple = getTab(which);
if (!selected_tuple)
{
return FALSE;
}
LLSD cbdata;
if (selected_tuple->mTabPanel)
cbdata = selected_tuple->mTabPanel->getName();
BOOL res = FALSE;
if( !mValidateSignal || (*mValidateSignal)( this, cbdata ) )
res = setTab(which);
if (res && mCommitSignal)
(*mCommitSignal)(this, cbdata);
return res;
BOOL LLTabContainer::setTab(S32 which)
{
static LLUICachedControl<S32> tabcntr_arrow_btn_size ("UITabCntrArrowBtnSize", 0);
LLTabTuple* selected_tuple = getTab(which);
if (!selected_tuple)
{
return FALSE;
}
Steven Bennetts
committed
BOOL is_visible = FALSE;
if (selected_tuple->mButton->getEnabled())
Steven Bennetts
committed
setCurrentPanelIndex(which);
S32 i = 0;
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
{
LLTabTuple* tuple = *iter;
BOOL is_selected = ( tuple == selected_tuple );
Merov Linden
committed
// Although the selected tab must be complete, we may have hollow LLTabTuple tucked in the list
Merov Linden
committed
if (tuple && tuple->mButton)
Merov Linden
committed
{
tuple->mButton->setUseEllipses(mUseTabEllipses);
tuple->mButton->setHAlign(mFontHalign);
tuple->mButton->setToggleState( is_selected );
// RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
tuple->mButton->setTabStop( is_selected );
}
Merov Linden
committed
if (tuple && tuple->mTabPanel)
Merov Linden
committed
{
tuple->mTabPanel->setVisible( is_selected );
//tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
}
if (is_selected)
{
// Make sure selected tab is within scroll region
Steven Bennetts
committed
if (mIsVertical)
Steven Bennetts
committed
S32 num_visible = getTabCount() - getMaxScrollPos();
if( i >= getScrollPos() && i <= getScrollPos() + num_visible)
{
setCurrentPanelIndex(which);
is_visible = TRUE;
}
else
{
is_visible = FALSE;
}
else if (getMaxScrollPos() > 0)
Steven Bennetts
committed
if( i < getScrollPos() )
{
setScrollPos(i);
}
else
S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1);
Merov Linden
committed
S32 running_tab_width = (tuple && tuple->mButton ? tuple->mButton->getRect().getWidth() : 0);
Steven Bennetts
committed
S32 j = i - 1;
S32 min_scroll_pos = i;
if (running_tab_width < available_width_with_arrows)
Steven Bennetts
committed
while (j >= 0)
Steven Bennetts
committed
LLTabTuple* other_tuple = getTab(j);
Merov Linden
committed
running_tab_width += (other_tuple && other_tuple->mButton ? other_tuple->mButton->getRect().getWidth() : 0);
Steven Bennetts
committed
if (running_tab_width > available_width_with_arrows)
{
break;
}
j--;
Steven Bennetts
committed
min_scroll_pos = j + 1;
Steven Bennetts
committed
setScrollPos(llclamp(getScrollPos(), min_scroll_pos, i));
setScrollPos(llmin(getScrollPos(), getMaxScrollPos()));
Steven Bennetts
committed
is_visible = TRUE;
else
{
is_visible = TRUE;
}
Steven Bennetts
committed
if (mIsVertical && getCurrentPanelIndex() >= 0)
Steven Bennetts
committed
LLTabTuple* tuple = getTab(getCurrentPanelIndex());
tuple->mTabPanel->setVisible( TRUE );
tuple->mButton->setToggleState( TRUE );
Steven Bennetts
committed
return is_visible;
BOOL LLTabContainer::selectTabByName(const std::string& name)
Steven Bennetts
committed
LLPanel* panel = getPanelByName(name);
if (!panel)
Merov Linden
committed
llwarns << "LLTabContainer::selectTabByName(" << name << ") failed" << llendl;
Steven Bennetts
committed
return FALSE;
}
Steven Bennetts
committed
BOOL result = selectTabPanel(panel);
return result;
}
BOOL LLTabContainer::getTabPanelFlashing(LLPanel *child)
{
LLTabTuple* tuple = getTabByPanel(child);
if( tuple )
{
return tuple->mButton->getFlashing();
Steven Bennetts
committed
return FALSE;
}
Steven Bennetts
committed
void LLTabContainer::setTabPanelFlashing(LLPanel* child, BOOL state )
{
LLTabTuple* tuple = getTabByPanel(child);
if( tuple )
Steven Bennetts
committed
tuple->mButton->setFlashing( state );
}
}
Steven Bennetts
committed
void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const LLColor4& color)
{
LLTabTuple* tuple = getTabByPanel(child);
if( tuple )
{
Paul Guslisty
committed
tuple->mButton->setImageOverlay(image_name, LLFontGL::LEFT, color);
Steven Bennetts
committed
}
}
void LLTabContainer::setTabImage(LLPanel* child, const LLUUID& image_id, const LLColor4& color)
{
LLTabTuple* tuple = getTabByPanel(child);
if( tuple )
{
Paul Guslisty
committed
tuple->mButton->setImageOverlay(image_id, LLFontGL::LEFT, color);
Paul Guslisty
committed
}
}
void LLTabContainer::setTabImage(LLPanel* child, LLIconCtrl* icon)
{
LLTabTuple* tuple = getTabByPanel(child);
LLCustomButtonIconCtrl* button;
if(tuple)
{
button = dynamic_cast<LLCustomButtonIconCtrl*>(tuple->mButton);
if(button)
{
button->setIcon(icon);
Paul Guslisty
committed
reshapeTuple(tuple);
Paul Guslisty
committed
}
}
void LLTabContainer::reshapeTuple(LLTabTuple* tuple)
Paul Guslisty
committed
{
static LLUICachedControl<S32> tab_padding ("UITabPadding", 0);
Paul Guslisty
committed
if (!mIsVertical)
{
Paul Guslisty
committed
S32 image_overlay_width = 0;
Paul Guslisty
committed
if(mCustomIconCtrlUsed)
{
LLCustomButtonIconCtrl* button = dynamic_cast<LLCustomButtonIconCtrl*>(tuple->mButton);
Paul Guslisty
committed
image_overlay_width = icon_ctrl ? icon_ctrl->getRect().getWidth() : 0;
}
else
{
image_overlay_width = tuple->mButton->getImageOverlay().notNull() ?
tuple->mButton->getImageOverlay()->getImage()->getWidth(0) : 0;
}
Paul Guslisty
committed
// remove current width from total tab strip width
mTotalTabWidth -= tuple->mButton->getRect().getWidth();
Paul Guslisty
committed
tuple->mPadding = image_overlay_width;
tuple->mButton->reshape(llclamp(mFont->getWidth(tuple->mButton->getLabelSelected()) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth),
tuple->mButton->getRect().getHeight());
// add back in button width to total tab strip width
mTotalTabWidth += tuple->mButton->getRect().getWidth();
// tabs have changed size, might need to scroll to see current tab
updateMaxScrollPos();
}
}
void LLTabContainer::setTitle(const std::string& title)
Steven Bennetts
committed
{
if (mTitleBox)
{
mTitleBox->setText( title );
}
}
const std::string LLTabContainer::getPanelTitle(S32 index)
Steven Bennetts
committed
{
if (index >= 0 && index < (S32)mTabList.size())
{
LLButton* tab_button = mTabList[index]->mButton;
return tab_button->getLabelSelected();
}
return LLStringUtil::null;
Steven Bennetts
committed
}
Steven Bennetts
committed
void LLTabContainer::setTopBorderHeight(S32 height)
{
mTopBorderHeight = height;
}
S32 LLTabContainer::getTopBorderHeight() const
{
return mTopBorderHeight;
}
void LLTabContainer::setRightTabBtnOffset(S32 offset)
{
Steven Bennetts
committed
mNextArrowBtn->translate( -offset - mRightTabBtnOffset, 0 );
mRightTabBtnOffset = offset;
updateMaxScrollPos();
}
void LLTabContainer::setPanelTitle(S32 index, const std::string& title)
static LLUICachedControl<S32> tab_padding ("UITabPadding", 0);
Steven Bennetts
committed
if (index >= 0 && index < getTabCount())
{
LLTabTuple* tuple = getTab(index);
LLButton* tab_button = tuple->mButton;
const LLFontGL* fontp = LLFontGL::getFontSansSerifSmall();
Steven Bennetts
committed
mTotalTabWidth -= tab_button->getRect().getWidth();
tab_button->reshape(llclamp(fontp->getWidth(title) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight());
Steven Bennetts
committed
mTotalTabWidth += tab_button->getRect().getWidth();
tab_button->setLabelSelected(title);
tab_button->setLabelUnselected(title);
}
updateMaxScrollPos();
}
Steven Bennetts
committed
void LLTabContainer::onTabBtn( const LLSD& data, LLPanel* panel )
Steven Bennetts
committed
{
LLTabTuple* tuple = getTabByPanel(panel);
selectTabPanel( panel );
Steven Bennetts
committed
Steven Bennetts
committed
}
void LLTabContainer::onNextBtn( const LLSD& data )
Steven Bennetts
committed
{
if (!mScrolled)
scrollNext();
mScrolled = FALSE;
void LLTabContainer::onNextBtnHeld( const LLSD& data )
if (mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME)
Steven Bennetts
committed
{
mScrollTimer.reset();
scrollNext();
mScrolled = TRUE;
Steven Bennetts
committed
}
}
void LLTabContainer::onPrevBtn( const LLSD& data )
Steven Bennetts
committed
{
if (!mScrolled)
Steven Bennetts
committed
{
scrollPrev();
mScrolled = FALSE;
Steven Bennetts
committed
}
void LLTabContainer::onJumpFirstBtn( const LLSD& data )
Steven Bennetts
committed
{
mScrollPos = 0;
Steven Bennetts
committed
}
void LLTabContainer::onJumpLastBtn( const LLSD& data )
Steven Bennetts
committed
{
mScrollPos = mMaxScrollPos;
Steven Bennetts
committed
}
void LLTabContainer::onPrevBtnHeld( const LLSD& data )
Steven Bennetts
committed
{
if (mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME)
mScrollTimer.reset();
scrollPrev();
mScrolled = TRUE;
Steven Bennetts
committed
// private
void LLTabContainer::initButtons()
Steven Bennetts
committed
// Hack:
if (getRect().getHeight() == 0 || mPrevArrowBtn)
Steven Bennetts
committed
return; // Don't have a rect yet or already got called
}
if (mIsVertical)
{
static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
Steven Bennetts
committed
// Left and right scroll arrows (for when there are too many tabs to show all at once).
S32 btn_top = getRect().getHeight();
S32 btn_top_lower = getRect().mBottom+tabcntrv_arrow_btn_size;
Steven Bennetts
committed
LLRect up_arrow_btn_rect;
up_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top, tabcntrv_arrow_btn_size, tabcntrv_arrow_btn_size );
Steven Bennetts
committed
LLRect down_arrow_btn_rect;
down_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top_lower, tabcntrv_arrow_btn_size, tabcntrv_arrow_btn_size );
LLButton::Params prev_btn_params;
prev_btn_params.name(std::string("Up Arrow"));
prev_btn_params.rect(up_arrow_btn_rect);
prev_btn_params.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT);
prev_btn_params.image_unselected.name("scrollbutton_up_out_blue.tga");
prev_btn_params.image_selected.name("scrollbutton_up_in_blue.tga");
prev_btn_params.click_callback.function(boost::bind(&LLTabContainer::onPrevBtn, this, _2));
mPrevArrowBtn = LLUICtrlFactory::create<LLButton>(prev_btn_params);
LLButton::Params next_btn_params;
next_btn_params.name(std::string("Down Arrow"));
next_btn_params.rect(down_arrow_btn_rect);
next_btn_params.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_LEFT);
next_btn_params.image_unselected.name("scrollbutton_down_out_blue.tga");
next_btn_params.image_selected.name("scrollbutton_down_in_blue.tga");
next_btn_params.click_callback.function(boost::bind(&LLTabContainer::onNextBtn, this, _2));
mNextArrowBtn = LLUICtrlFactory::create<LLButton>(next_btn_params);
Steven Bennetts
committed
}
else // Horizontal
{
static LLUICachedControl<S32> tabcntr_arrow_btn_size ("UITabCntrArrowBtnSize", 0);
Steven Bennetts
committed
S32 arrow_fudge = 1; // match new art better
// Left and right scroll arrows (for when there are too many tabs to show all at once).
S32 btn_top = (getTabPosition() == TOP ) ? getRect().getHeight() - getTopBorderHeight() : tabcntr_arrow_btn_size + 1;
Steven Bennetts
committed
LLRect left_arrow_btn_rect;
left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1+tabcntr_arrow_btn_size, btn_top + arrow_fudge, tabcntr_arrow_btn_size, mTabHeight );
Steven Bennetts
committed
LLRect jump_left_arrow_btn_rect;
jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, tabcntr_arrow_btn_size, mTabHeight );
Steven Bennetts
committed
S32 right_pad = tabcntr_arrow_btn_size + LLPANEL_BORDER_WIDTH + 1;
Steven Bennetts
committed
LLRect right_arrow_btn_rect;
right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad - tabcntr_arrow_btn_size,
Steven Bennetts
committed
btn_top + arrow_fudge,
tabcntr_arrow_btn_size, mTabHeight );
Steven Bennetts
committed
LLRect jump_right_arrow_btn_rect;
jump_right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad,
btn_top + arrow_fudge,
tabcntr_arrow_btn_size, mTabHeight );
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
LLButton::Params p;
p.name(std::string("Jump Left Arrow"));
p.image_unselected.name("jump_left_out.tga");
p.image_selected.name("jump_left_in.tga");
p.click_callback.function(boost::bind(&LLTabContainer::onJumpFirstBtn, this, _2));
p.rect(jump_left_arrow_btn_rect);
p.follows.flags(FOLLOWS_LEFT);
mJumpPrevArrowBtn = LLUICtrlFactory::create<LLButton>(p);
p = LLButton::Params();
p.name(std::string("Left Arrow"));
p.rect(left_arrow_btn_rect);
p.follows.flags(FOLLOWS_LEFT);
p.image_unselected.name("scrollbutton_left_out_blue.tga");
p.image_selected.name("scrollbutton_left_in_blue.tga");
p.click_callback.function(boost::bind(&LLTabContainer::onPrevBtn, this, _2));
p.mouse_held_callback.function(boost::bind(&LLTabContainer::onPrevBtnHeld, this, _2));
mPrevArrowBtn = LLUICtrlFactory::create<LLButton>(p);
p = LLButton::Params();
p.name(std::string("Jump Right Arrow"));
p.rect(jump_right_arrow_btn_rect);
p.follows.flags(FOLLOWS_RIGHT);
p.image_unselected.name("jump_right_out.tga");
p.image_selected.name("jump_right_in.tga");
p.click_callback.function(boost::bind(&LLTabContainer::onJumpLastBtn, this, _2));
mJumpNextArrowBtn = LLUICtrlFactory::create<LLButton>(p);
p = LLButton::Params();
p.name(std::string("Right Arrow"));
p.rect(right_arrow_btn_rect);
p.follows.flags(FOLLOWS_RIGHT);
p.image_unselected.name("scrollbutton_right_out_blue.tga");
p.image_selected.name("scrollbutton_right_in_blue.tga");
p.click_callback.function(boost::bind(&LLTabContainer::onNextBtn, this, _2));
p.mouse_held_callback.function(boost::bind(&LLTabContainer::onNextBtnHeld, this, _2));
mNextArrowBtn = LLUICtrlFactory::create<LLButton>(p);
Steven Bennetts
committed
if( getTabPosition() == TOP )
Steven Bennetts
committed
mNextArrowBtn->setFollowsTop();
mPrevArrowBtn->setFollowsTop();
mJumpPrevArrowBtn->setFollowsTop();
mJumpNextArrowBtn->setFollowsTop();
}
else
{
mNextArrowBtn->setFollowsBottom();
mPrevArrowBtn->setFollowsBottom();
mJumpPrevArrowBtn->setFollowsBottom();
mJumpNextArrowBtn->setFollowsBottom();
Steven Bennetts
committed
mPrevArrowBtn->setTabStop(FALSE);
addChild(mPrevArrowBtn);
Steven Bennetts
committed
mNextArrowBtn->setTabStop(FALSE);
addChild(mNextArrowBtn);
Steven Bennetts
committed
if (mJumpPrevArrowBtn)
Steven Bennetts
committed
mJumpPrevArrowBtn->setTabStop(FALSE);
addChild(mJumpPrevArrowBtn);
Steven Bennetts
committed
if (mJumpNextArrowBtn)
Steven Bennetts
committed
mJumpNextArrowBtn->setTabStop(FALSE);
addChild(mJumpNextArrowBtn);
Steven Bennetts
committed
// set default tab group to be panel contents
setDefaultTabGroup(1);
}
//this is a work around for the current LLPanel::initFromParams hack
//so that it doesn't overwrite the default tab group.
//will be removed when LLPanel is fixed soon.
void LLTabContainer::initFromParams(const LLPanel::Params& p)
{
LLPanel::initFromParams(p);
setDefaultTabGroup(1);
}
LLTabTuple* LLTabContainer::getTabByPanel(LLPanel* child)
Steven Bennetts
committed
{
for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter)
Steven Bennetts
committed
LLTabTuple* tuple = *iter;
if( tuple->mTabPanel == child )
Steven Bennetts
committed
return tuple;
Steven Bennetts
committed
return NULL;
}
Steven Bennetts
committed
void LLTabContainer::insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_point)
{
switch(insertion_point)
Steven Bennetts
committed
case START:
// insert the new tab in the front of the list
mTabList.insert(mTabList.begin() + mLockedTabCount, tuple);
break;
case LEFT_OF_CURRENT:
// insert the new tab before the current tab (but not before mLockedTabCount)
Steven Bennetts
committed
tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx);
mTabList.insert(current_iter, tuple);
}
break;
case RIGHT_OF_CURRENT:
// insert the new tab after the current tab (but not before mLockedTabCount)
{
tuple_list_t::iterator current_iter = mTabList.begin() + llmax(mLockedTabCount, mCurrentTabIdx + 1);
mTabList.insert(current_iter, tuple);
Steven Bennetts
committed
break;
case END:
default:
mTabList.push_back( tuple );
Steven Bennetts
committed
void LLTabContainer::updateMaxScrollPos()
static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0);
Steven Bennetts
committed
BOOL no_scroll = TRUE;
if (mIsVertical)
S32 tab_total_height = (BTN_HEIGHT + tabcntrv_pad) * getTabCount();
Steven Bennetts
committed
S32 available_height = getRect().getHeight() - getTopBorderHeight();
if( tab_total_height > available_height )
static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0);
S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad);
Steven Bennetts
committed
S32 additional_needed = tab_total_height - available_height_with_arrows;
setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) );