diff options
Diffstat (limited to 'indra/llui/lltabcontainer.cpp')
-rw-r--r-- | indra/llui/lltabcontainer.cpp | 790 |
1 files changed, 371 insertions, 419 deletions
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index f4169488d4..5b24131c90 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -35,73 +35,127 @@ #include "llfocusmgr.h" #include "llbutton.h" #include "llrect.h" -#include "llresmgr.h" #include "llresizehandle.h" #include "lltextbox.h" #include "llcriticaldamp.h" #include "lluictrlfactory.h" -#include "lltabcontainervertical.h" #include "llrender.h" +#include "llfloater.h" + +//---------------------------------------------------------------------------- + +// Implementation Notes: +// - Each tab points to a LLPanel (see LLTabTuple below) +// - When a tab is selected, the validation callback +// (LLUICtrl::mValidateSignal) is called +// - If the validation callback returns true (or none is provided), +// the tab is changed and the commit callback +// (LLUICtrl::mCommitSignal) is called +// - Callbacks pass the LLTabContainer as the control, +// and the NAME of the selected PANEL as the LLSD data + +//---------------------------------------------------------------------------- const F32 SCROLL_STEP_TIME = 0.4f; const F32 SCROLL_DELAY_TIME = 0.5f; -const S32 TAB_PADDING = 15; -const S32 TABCNTR_TAB_MIN_WIDTH = 60; -const S32 TABCNTR_VERT_TAB_MIN_WIDTH = 100; -const S32 TABCNTR_TAB_MAX_WIDTH = 150; -const S32 TABCNTR_TAB_PARTIAL_WIDTH = 12; // When tabs are parially obscured, how much can you still see. -const S32 TABCNTR_TAB_HEIGHT = 16; -const S32 TABCNTR_ARROW_BTN_SIZE = 16; -const S32 TABCNTR_BUTTON_PANEL_OVERLAP = 1; // how many pixels the tab buttons and tab panels overlap. -const S32 TABCNTR_TAB_H_PAD = 4; - -const S32 TABCNTR_CLOSE_BTN_SIZE = 16; -const S32 TABCNTR_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTR_CLOSE_BTN_SIZE; - -const S32 TABCNTRV_CLOSE_BTN_SIZE = 16; -const S32 TABCNTRV_HEADER_HEIGHT = LLPANEL_BORDER_WIDTH + TABCNTRV_CLOSE_BTN_SIZE; -//const S32 TABCNTRV_TAB_WIDTH = 100; -const S32 TABCNTRV_ARROW_BTN_SIZE = 16; -const S32 TABCNTRV_PAD = 0; - -static LLRegisterWidget<LLTabContainer> r("tab_container"); - -LLTabContainer::LLTabContainer(const std::string& name, const LLRect& rect, TabPosition pos, - BOOL bordered, BOOL is_vertical ) - : - LLPanel(name, rect, bordered), + +void LLTabContainer::TabPositions::declareValues() +{ + declare("top", LLTabContainer::TOP); + declare("bottom", LLTabContainer::BOTTOM); + declare("left", LLTabContainer::LEFT); +} + +//---------------------------------------------------------------------------- + +// Structure used to map tab buttons to and from tab panels +class LLTabTuple +{ +public: + LLTabTuple( LLTabContainer* c, LLPanel* p, LLButton* b, LLTextBox* placeholder = NULL) + : + mTabContainer(c), + mTabPanel(p), + mButton(b), + mOldState(FALSE), + mPlaceholderText(placeholder), + mPadding(0) + {} + + LLTabContainer* mTabContainer; + LLPanel* mTabPanel; + LLButton* mButton; + BOOL mOldState; + LLTextBox* mPlaceholderText; + S32 mPadding; +}; + +//---------------------------------------------------------------------------- + +struct LLPlaceHolderPanel : public LLPanel +{ + // create dummy param block to register with "placeholder" nane + struct Params : public LLPanel::Params{}; + LLPlaceHolderPanel(const Params& p) : LLPanel(p) + {} +}; +static LLRegisterWidget<LLPlaceHolderPanel> r1("placeholder"); +static LLRegisterWidget<LLTabContainer> r2("tab_container"); + +LLTabContainer::Params::Params() +: tab_width("tab_width"), + tab_position("tab_position"), + tab_min_width("tab_min_width"), + tab_max_width("tab_max_width"), + hide_tabs("hide_tabs", false) +{ + name(std::string("tab_container")); + mouse_opaque = false; +} + +LLTabContainer::LLTabContainer(const LLTabContainer::Params& p) +: LLPanel(p), mCurrentTabIdx(-1), - mNextTabIdx(-1), - mTabsHidden(FALSE), + mTabsHidden(p.hide_tabs), mScrolled(FALSE), mScrollPos(0), mScrollPosPixels(0), mMaxScrollPos(0), - mCloseCallback( NULL ), - mCallbackUserdata( NULL ), mTitleBox(NULL), mTopBorderHeight(LLPANEL_BORDER_WIDTH), - mTabPosition(pos), mLockedTabCount(0), - mMinTabWidth(TABCNTR_TAB_MIN_WIDTH), - mMaxTabWidth(TABCNTR_TAB_MAX_WIDTH), + mMinTabWidth(0), + mMaxTabWidth(p.tab_max_width), mPrevArrowBtn(NULL), mNextArrowBtn(NULL), - mIsVertical(is_vertical), + mIsVertical( p.tab_position == LEFT ), // Horizontal Specific mJumpPrevArrowBtn(NULL), mJumpNextArrowBtn(NULL), - mRightTabBtnOffset(0), - mTotalTabWidth(0) -{ - //RN: HACK to support default min width for legacy vertical tab containers - if (mIsVertical) + mRightTabBtnOffset(p.tab_padding_right), + mTotalTabWidth(0), + mTabPosition(p.tab_position) +{ + static LLUICachedControl<S32> tabcntr_vert_tab_min_width ("UITabCntrVertTabMinWidth", 0); + + mDragAndDropDelayTimer.stop(); + + if (p.tab_width.isProvided()) + { + mMinTabWidth = p.tab_width; + } + else if (!mIsVertical) { - mMinTabWidth = TABCNTR_VERT_TAB_MIN_WIDTH; + mMinTabWidth = p.tab_min_width; } - setMouseOpaque(FALSE); + else + { + // *HACK: support default min width for legacy vertical + // tab containers + mMinTabWidth = tabcntr_vert_tab_min_width; + } + initButtons( ); - mDragAndDropDelayTimer.stop(); } LLTabContainer::~LLTabContainer() @@ -150,16 +204,45 @@ LLView* LLTabContainer::getChildView(const std::string& name, BOOL recurse, BOOL return LLView::getChildView(name, recurse, create_if_missing); } +bool LLTabContainer::addChild(LLView* view, S32 tab_group) +{ + LLPanel* panelp = dynamic_cast<LLPanel*>(view); + + if (panelp) + { + panelp->setSaveToXML(TRUE); + + addTabPanel(TabPanelParams().panel(panelp).label(panelp->getLabel()).is_placeholder(dynamic_cast<LLPlaceHolderPanel*>(view) != NULL)); + return true; + } + else + { + return LLUICtrl::addChild(view, tab_group); + } +} + +BOOL LLTabContainer::postBuild() +{ + selectFirstTab(); + + return TRUE; +} + // virtual void LLTabContainer::draw() { + static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0); + static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0); + static LLUICachedControl<S32> tabcntr_tab_h_pad ("UITabCntrTabHPad", 0); + static LLUICachedControl<S32> tabcntr_arrow_btn_size ("UITabCntrArrowBtnSize", 0); + static LLUICachedControl<S32> tabcntr_tab_partial_width ("UITabCntrTabPartialWidth", 0); S32 target_pixel_scroll = 0; S32 cur_scroll_pos = getScrollPos(); if (cur_scroll_pos > 0) { + S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1); if (!mIsVertical) { - S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { if (cur_scroll_pos == 0) @@ -171,26 +254,10 @@ void LLTabContainer::draw() } // Show part of the tab to the left of what is fully visible - target_pixel_scroll -= TABCNTR_TAB_PARTIAL_WIDTH; + target_pixel_scroll -= tabcntr_tab_partial_width; // clamp so that rightmost tab never leaves right side of screen target_pixel_scroll = llmin(mTotalTabWidth - available_width_with_arrows, target_pixel_scroll); } - else - { - S32 available_height_with_arrows = getRect().getHeight() - getTopBorderHeight() - (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); - for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) - { - if (cur_scroll_pos==0) - { - break; - } - target_pixel_scroll += (*iter)->mButton->getRect().getHeight(); - cur_scroll_pos--; - } - S32 total_tab_height = (BTN_HEIGHT + TABCNTRV_PAD) * getTabCount() + TABCNTRV_PAD; - // clamp so that the bottom tab never leaves bottom of panel - target_pixel_scroll = llmin(total_tab_height - available_height_with_arrows, target_pixel_scroll); - } } setScrollPosPixels((S32)lerp((F32)getScrollPosPixels(), (F32)target_pixel_scroll, LLCriticalDamp::getInterpolant(0.08f))); @@ -207,13 +274,13 @@ void LLTabContainer::draw() S32 left = 0, top = 0; if (mIsVertical) { - top = getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1 - (has_scroll_arrows ? TABCNTRV_ARROW_BTN_SIZE : 0); + top = getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1 - (has_scroll_arrows ? tabcntrv_arrow_btn_size : 0); top += getScrollPosPixels(); } else { // Set the leftmost position of the tab buttons. - left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (TABCNTR_ARROW_BTN_SIZE * 2) : TABCNTR_TAB_H_PAD); + left = LLPANEL_BORDER_WIDTH + (has_scroll_arrows ? (tabcntr_arrow_btn_size * 2) : tabcntr_tab_h_pad); left -= getScrollPosPixels(); } @@ -243,8 +310,8 @@ void LLTabContainer::draw() // ...but clip them. if (mIsVertical) { - clip_rect.mBottom = mNextArrowBtn->getRect().mTop + 3*TABCNTRV_PAD; - clip_rect.mTop = mPrevArrowBtn->getRect().mBottom - 3*TABCNTRV_PAD; + clip_rect.mBottom = mNextArrowBtn->getRect().mTop + 3*tabcntrv_pad; + clip_rect.mTop = mPrevArrowBtn->getRect().mBottom - 3*tabcntrv_pad; } else { @@ -262,7 +329,7 @@ void LLTabContainer::draw() tuple->mButton->translate( left ? left - tuple->mButton->getRect().mLeft : 0, top ? top - tuple->mButton->getRect().mTop : 0 ); - if (top) top -= BTN_HEIGHT + TABCNTRV_PAD; + if (top) top -= BTN_HEIGHT + tabcntrv_pad; if (left) left += tuple->mButton->getRect().getWidth(); if (!mIsVertical) @@ -316,6 +383,7 @@ void LLTabContainer::draw() // virtual BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) { + static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0); BOOL handled = FALSE; BOOL has_scroll_arrows = (getMaxScrollPos() > 0); @@ -359,9 +427,9 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) if (mIsVertical) { tab_rect = LLRect(firsttuple->mButton->getRect().mLeft, - has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - TABCNTRV_PAD : mPrevArrowBtn->getRect().mTop, + has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - tabcntrv_pad : mPrevArrowBtn->getRect().mTop, firsttuple->mButton->getRect().mRight, - has_scroll_arrows ? mNextArrowBtn->getRect().mTop + TABCNTRV_PAD : mNextArrowBtn->getRect().mBottom ); + has_scroll_arrows ? mNextArrowBtn->getRect().mTop + tabcntrv_pad : mNextArrowBtn->getRect().mBottom ); } else { @@ -483,6 +551,7 @@ BOOL LLTabContainer::handleMouseUp( S32 x, S32 y, MASK mask ) // virtual BOOL LLTabContainer::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rect ) { + static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0); BOOL handled = LLPanel::handleToolTip( x, y, msg, sticky_rect ); if (!handled && getTabCount() > 0) { @@ -493,9 +562,9 @@ BOOL LLTabContainer::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* stic if (mIsVertical) { clip = LLRect(firsttuple->mButton->getRect().mLeft, - has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - TABCNTRV_PAD : mPrevArrowBtn->getRect().mTop, + has_scroll_arrows ? mPrevArrowBtn->getRect().mBottom - tabcntrv_pad : mPrevArrowBtn->getRect().mTop, firsttuple->mButton->getRect().mRight, - has_scroll_arrows ? mNextArrowBtn->getRect().mTop + TABCNTRV_PAD : mNextArrowBtn->getRect().mBottom ); + has_scroll_arrows ? mNextArrowBtn->getRect().mTop + tabcntrv_pad : mNextArrowBtn->getRect().mBottom ); } else { @@ -617,14 +686,6 @@ BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask) } // virtual -LLXMLNodePtr LLTabContainer::getXML(bool save_children) const -{ - LLXMLNodePtr node = LLPanel::getXML(); - node->createChild("tab_position", TRUE)->setStringValue((getTabPosition() == TOP ? "top" : "bottom")); - return node; -} - -// virtual BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType type, void* cargo_data, EAcceptance *accept, std::string &tooltip) { BOOL has_scroll_arrows = (getMaxScrollPos() > 0); @@ -676,21 +737,33 @@ BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDrag return LLView::handleDragAndDrop(x, y, mask, drop, type, cargo_data, accept, tooltip); } -void LLTabContainer::addTabPanel(LLPanel* child, - const std::string& label, - BOOL select, - void (*on_tab_clicked)(void*, bool), - void* userdata, - S32 indent, - BOOL placeholder, - eInsertionPoint insertion_point) +void LLTabContainer::addTabPanel(LLPanel* panelp) +{ + addTabPanel(TabPanelParams().panel(panelp)); +} + +void LLTabContainer::addTabPanel(const TabPanelParams& panel) { + LLPanel* child = panel.panel(); + const std::string& label = panel.label.isProvided() + ? panel.label() + : panel.panel()->getLabel(); + BOOL select = panel.select_tab(); + S32 indent = panel.indent(); + BOOL placeholder = panel.is_placeholder; + eInsertionPoint insertion_point = panel.insert_at(); + + static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0); + static LLUICachedControl<S32> tabcntr_button_panel_overlap ("UITabCntrButtonPanelOverlap", 0); + static LLUICachedControl<S32> tabcntr_tab_height ("UITabCntrTabHeight", 0); + static LLUICachedControl<S32> tab_padding ("UITabPadding", 0); if (child->getParent() == this) { // already a child of mine return; } - const LLFontGL* font = LLResMgr::getInstance()->getRes( mIsVertical ? LLFONT_SANSSERIF : LLFONT_SANSSERIF_SMALL ); + const LLFontGL* font = + (mIsVertical ? LLFontGL::getFontSansSerif() : LLFontGL::getFontSansSerifSmall()); // Store the original label for possible xml export. child->setLabel(label); @@ -700,7 +773,7 @@ void LLTabContainer::addTabPanel(LLPanel* child, S32 button_width = mMinTabWidth; if (!mIsVertical) { - button_width = llclamp(font->getWidth(trimmed_label) + TAB_PADDING, mMinTabWidth, mMaxTabWidth); + button_width = llclamp(font->getWidth(trimmed_label) + tab_padding, mMinTabWidth, mMaxTabWidth); } // Tab panel @@ -708,20 +781,20 @@ void LLTabContainer::addTabPanel(LLPanel* child, S32 tab_panel_bottom; if( getTabPosition() == LLTabContainer::TOP ) { - S32 tab_height = mIsVertical ? BTN_HEIGHT : TABCNTR_TAB_HEIGHT; - tab_panel_top = getRect().getHeight() - getTopBorderHeight() - (tab_height - TABCNTR_BUTTON_PANEL_OVERLAP); + S32 tab_height = mIsVertical ? BTN_HEIGHT : tabcntr_tab_height; + tab_panel_top = getRect().getHeight() - getTopBorderHeight() - (tab_height - tabcntr_button_panel_overlap); tab_panel_bottom = LLPANEL_BORDER_WIDTH; } else { tab_panel_top = getRect().getHeight() - getTopBorderHeight(); - tab_panel_bottom = (TABCNTR_TAB_HEIGHT - TABCNTR_BUTTON_PANEL_OVERLAP); // Run to the edge, covering up the border + tab_panel_bottom = (tabcntr_tab_height - tabcntr_button_panel_overlap); // Run to the edge, covering up the border } LLRect tab_panel_rect; if (mIsVertical) { - tab_panel_rect = LLRect(mMinTabWidth + (LLPANEL_BORDER_WIDTH * 2) + TABCNTRV_PAD, + tab_panel_rect = LLRect(mMinTabWidth + (LLPANEL_BORDER_WIDTH * 2) + tabcntrv_pad, getRect().getHeight() - LLPANEL_BORDER_WIDTH, getRect().getWidth() - LLPANEL_BORDER_WIDTH, LLPANEL_BORDER_WIDTH); @@ -750,20 +823,20 @@ void LLTabContainer::addTabPanel(LLPanel* child, if (mIsVertical) { - btn_rect.setLeftTopAndSize(TABCNTRV_PAD + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor - (getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + TABCNTRV_PAD) * getTabCount()), + btn_rect.setLeftTopAndSize(tabcntrv_pad + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor + (getRect().getHeight() - getTopBorderHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + tabcntrv_pad) * getTabCount()), mMinTabWidth, BTN_HEIGHT); } else if( getTabPosition() == LLTabContainer::TOP ) { - btn_rect.setLeftTopAndSize( 0, getRect().getHeight() - getTopBorderHeight() + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); + btn_rect.setLeftTopAndSize( 0, getRect().getHeight() - getTopBorderHeight() + tab_fudge, button_width, tabcntr_tab_height ); tab_img = "tab_top_blue.tga"; tab_selected_img = "tab_top_selected_blue.tga"; } else { - btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, TABCNTR_TAB_HEIGHT ); + btn_rect.setOriginAndSize( 0, 0 + tab_fudge, button_width, tabcntr_tab_height ); tab_img = "tab_bottom_blue.tga"; tab_selected_img = "tab_bottom_selected_blue.tga"; } @@ -774,31 +847,38 @@ void LLTabContainer::addTabPanel(LLPanel* child, if (placeholder) { btn_rect.translate(0, -LLBUTTON_V_PAD-2); - textbox = new LLTextBox(trimmed_label, btn_rect, trimmed_label, font); + LLTextBox::Params params; + params.name(trimmed_label); + params.rect(btn_rect); + params.text(trimmed_label); + params.font(font); + textbox = LLUICtrlFactory::create<LLTextBox> (params); - btn = new LLButton(LLStringUtil::null, LLRect(0,0,0,0)); + LLButton::Params p; + p.name(""); + btn = LLUICtrlFactory::create<LLButton>(p); } else { if (mIsVertical) { - btn = new LLButton(std::string("vert tab button"), - btn_rect, - LLStringUtil::null, - LLStringUtil::null, - LLStringUtil::null, - &LLTabContainer::onTabBtn, NULL, - font, - trimmed_label, trimmed_label); - btn->setImages(std::string("tab_left.tga"), std::string("tab_left_selected.tga")); - btn->setScaleImage(TRUE); - btn->setHAlign(LLFontGL::LEFT); - btn->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT); - btn->setTabStop(FALSE); + LLButton::Params p; + p.name(std::string("vert tab button")); + p.rect(btn_rect); + p.follows.flags(FOLLOWS_TOP | FOLLOWS_LEFT); + p.click_callback.function(boost::bind(&LLTabContainer::onTabBtn, this, _2, child)); + p.font(font); + p.label(trimmed_label); + p.image_unselected.name("tab_left.tga"); + p.image_selected.name("tab_left_selected.tga"); + p.scale_image(true); + p.font_halign = LLFontGL::LEFT; + p.tab_stop(false); if (indent) { - btn->setLeftHPad(indent); + p.pad_left(indent); } + btn = LLUICtrlFactory::create<LLButton>(p); } else { @@ -806,39 +886,44 @@ void LLTabContainer::addTabPanel(LLPanel* child, tooltip += "\nAlt-Left arrow for previous tab"; tooltip += "\nAlt-Right arrow for next tab"; - btn = new LLButton(std::string(child->getName()) + " tab", - btn_rect, - LLStringUtil::null, LLStringUtil::null, LLStringUtil::null, - &LLTabContainer::onTabBtn, NULL, // set userdata below - font, - trimmed_label, trimmed_label ); - btn->setVisible( FALSE ); - btn->setToolTip( tooltip ); - btn->setScaleImage(TRUE); - btn->setImages(tab_img, tab_selected_img); - + LLButton::Params p; + p.name(std::string(child->getName()) + " tab"); + p.rect(btn_rect); + p.click_callback.function(boost::bind(&LLTabContainer::onTabBtn, this, _2, child)); + p.font(font); + p.label(trimmed_label); + p.visible(false); + p.tool_tip(tooltip); + p.scale_image(true); + p.image_unselected.name(tab_img); + p.image_selected.name(tab_selected_img); + p.tab_stop(false); // Try to squeeze in a bit more text - btn->setLeftHPad( 4 ); - btn->setRightHPad( 2 ); - btn->setHAlign(LLFontGL::LEFT); - btn->setTabStop(FALSE); + p.pad_left(4); + p.pad_right(2); + p.font_halign = LLFontGL::LEFT; + p.follows.flags = FOLLOWS_LEFT; + p.follows.flags = FOLLOWS_LEFT; + if (indent) { - btn->setLeftHPad(indent); + p.pad_left(indent); } if( getTabPosition() == TOP ) { - btn->setFollowsTop(); + p.follows.flags = p.follows.flags() | FOLLOWS_TOP; } else { - btn->setFollowsBottom(); + p.follows.flags = p.follows.flags() | FOLLOWS_BOTTOM; } + + btn = LLUICtrlFactory::create<LLButton>(p); } } - LLTabTuple* tuple = new LLTabTuple( this, child, btn, on_tab_clicked, userdata, textbox ); + LLTabTuple* tuple = new LLTabTuple( this, child, btn, textbox ); insertTuple( tuple, insertion_point ); if (textbox) @@ -849,12 +934,11 @@ void LLTabContainer::addTabPanel(LLPanel* child, if (btn) { btn->setSaveToXML(false); - btn->setCallbackUserData( tuple ); addChild( btn, 0 ); } if (child) { - addChild(child, 1); + LLUICtrl::addChild(child, 1); } if( select ) @@ -867,11 +951,12 @@ void LLTabContainer::addTabPanel(LLPanel* child, void LLTabContainer::addPlaceholder(LLPanel* child, const std::string& label) { - addTabPanel(child, label, FALSE, NULL, NULL, 0, TRUE); + addTabPanel(TabPanelParams().panel(child).label(label).is_placeholder(true)); } void LLTabContainer::removeTabPanel(LLPanel* child) { + static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0); if (mIsVertical) { // Fix-up button sizes @@ -880,8 +965,8 @@ void LLTabContainer::removeTabPanel(LLPanel* child) { 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)), + rect.setLeftTopAndSize(tabcntrv_pad + LLPANEL_BORDER_WIDTH + 2, // JC - Fudge factor + (getRect().getHeight() - LLPANEL_BORDER_WIDTH - 1) - ((BTN_HEIGHT + tabcntrv_pad) * (tab_count)), mMinTabWidth, BTN_HEIGHT); if (tuple->mPlaceholderText) @@ -1044,7 +1129,7 @@ S32 LLTabContainer::getPanelIndexByTitle(const std::string& title) return -1; } -LLPanel *LLTabContainer::getPanelByName(const std::string& name) +LLPanel* LLTabContainer::getPanelByName(const std::string& name) { for (S32 index = 0 ; index < (S32)mTabList.size(); index++) { @@ -1138,42 +1223,36 @@ BOOL LLTabContainer::selectTabPanel(LLPanel* child) BOOL LLTabContainer::selectTab(S32 which) { - if (which >= getTabCount()) return FALSE; - if (which < 0) return FALSE; - - //if( gFocusMgr.childHasKeyboardFocus( this ) ) - //{ - // gFocusMgr.setKeyboardFocus( NULL ); - //} + if (which >= getTabCount() || which < 0) + return FALSE; LLTabTuple* selected_tuple = getTab(which); if (!selected_tuple) { return FALSE; } + + LLSD cbdata; + if (selected_tuple->mTabPanel) + cbdata = selected_tuple->mTabPanel->getName(); - if (!selected_tuple->mPrecommitChangeCallback) + BOOL res = FALSE; + if( mValidateSignal( this, cbdata ) ) { - return setTab(which); + res = setTab(which); + if (res) + { + mCommitSignal(this, cbdata); + } } - - mNextTabIdx = which; - selected_tuple->mPrecommitChangeCallback(selected_tuple->mUserData, false); - return TRUE; + + return res; } +// private BOOL LLTabContainer::setTab(S32 which) { - if (which == -1) - { - if (mNextTabIdx == -1) - { - return FALSE; - } - which = mNextTabIdx; - mNextTabIdx = -1; - } - + static LLUICachedControl<S32> tabcntr_arrow_btn_size ("UITabCntrArrowBtnSize", 0); LLTabTuple* selected_tuple = getTab(which); if (!selected_tuple) { @@ -1196,7 +1275,7 @@ BOOL LLTabContainer::setTab(S32 which) // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs tuple->mButton->setTabStop( is_selected ); - if( is_selected && (mIsVertical || (getMaxScrollPos() > 0))) + if (is_selected) { // Make sure selected tab is within scroll region if (mIsVertical) @@ -1212,7 +1291,7 @@ BOOL LLTabContainer::setTab(S32 which) is_visible = FALSE; } } - else + else if (getMaxScrollPos() > 0) { if( i < getScrollPos() ) { @@ -1220,7 +1299,7 @@ BOOL LLTabContainer::setTab(S32 which) } else { - S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); + S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1); S32 running_tab_width = tuple->mButton->getRect().getWidth(); S32 j = i - 1; S32 min_scroll_pos = i; @@ -1243,13 +1322,13 @@ BOOL LLTabContainer::setTab(S32 which) } is_visible = TRUE; } + else + { + is_visible = TRUE; + } } i++; } - if( selected_tuple->mOnChangeCallback ) - { - selected_tuple->mOnChangeCallback( selected_tuple->mUserData, false ); - } } if (mIsVertical && getCurrentPanelIndex() >= 0) { @@ -1295,6 +1374,7 @@ void LLTabContainer::setTabPanelFlashing(LLPanel* child, BOOL state ) void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const LLColor4& color) { + static LLUICachedControl<S32> tab_padding ("UITabPadding", 0); LLTabTuple* tuple = getTabByPanel(child); if( tuple ) { @@ -1302,7 +1382,7 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L if (!mIsVertical) { - const LLFontGL* fontp = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ); + const LLFontGL* fontp = LLFontGL::getFontSansSerifSmall(); // remove current width from total tab strip width mTotalTabWidth -= tuple->mButton->getRect().getWidth(); @@ -1313,7 +1393,7 @@ void LLTabContainer::setTabImage(LLPanel* child, std::string image_name, const L tuple->mPadding = image_overlay_width; tuple->mButton->setRightHPad(6); - tuple->mButton->reshape(llclamp(fontp->getWidth(tuple->mButton->getLabelSelected()) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), + tuple->mButton->reshape(llclamp(fontp->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(); @@ -1352,33 +1432,6 @@ S32 LLTabContainer::getTopBorderHeight() const return mTopBorderHeight; } -void LLTabContainer::setTabChangeCallback(LLPanel* tab, void (*on_tab_clicked)(void*, bool)) -{ - LLTabTuple* tuplep = getTabByPanel(tab); - if (tuplep) - { - tuplep->mOnChangeCallback = on_tab_clicked; - } -} - -void LLTabContainer::setTabPrecommitChangeCallback(LLPanel* tab, void (*on_precommit)(void*, bool)) -{ - LLTabTuple* tuplep = getTabByPanel(tab); - if (tuplep) - { - tuplep->mPrecommitChangeCallback = on_precommit; - } -} - -void LLTabContainer::setTabUserData(LLPanel* tab, void* userdata) -{ - LLTabTuple* tuplep = getTabByPanel(tab); - if (tuplep) - { - tuplep->mUserData = userdata; - } -} - void LLTabContainer::setRightTabBtnOffset(S32 offset) { mNextArrowBtn->translate( -offset - mRightTabBtnOffset, 0 ); @@ -1388,13 +1441,15 @@ void LLTabContainer::setRightTabBtnOffset(S32 offset) void LLTabContainer::setPanelTitle(S32 index, const std::string& title) { + static LLUICachedControl<S32> tab_padding ("UITabPadding", 0); + if (index >= 0 && index < getTabCount()) { LLTabTuple* tuple = getTab(index); LLButton* tab_button = tuple->mButton; - const LLFontGL* fontp = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ); + const LLFontGL* fontp = LLFontGL::getFontSansSerifSmall(); mTotalTabWidth -= tab_button->getRect().getWidth(); - tab_button->reshape(llclamp(fontp->getWidth(title) + TAB_PADDING + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight()); + tab_button->reshape(llclamp(fontp->getWidth(title) + tab_padding + tuple->mPadding, mMinTabWidth, mMaxTabWidth), tab_button->getRect().getHeight()); mTotalTabWidth += tab_button->getRect().getWidth(); tab_button->setLabelSelected(title); tab_button->setLabelUnselected(title); @@ -1403,184 +1458,62 @@ void LLTabContainer::setPanelTitle(S32 index, const std::string& title) } -// static -void LLTabContainer::onTabBtn( void* userdata ) +void LLTabContainer::onTabBtn( const LLSD& data, LLPanel* panel ) { - LLTabTuple* tuple = (LLTabTuple*) userdata; - LLTabContainer* self = tuple->mTabContainer; - self->selectTabPanel( tuple->mTabPanel ); + LLTabTuple* tuple = getTabByPanel(panel); + selectTabPanel( panel ); tuple->mTabPanel->setFocus(TRUE); } -// static -void LLTabContainer::onCloseBtn( void* userdata ) -{ - LLTabContainer* self = (LLTabContainer*) userdata; - if( self->mCloseCallback ) - { - self->mCloseCallback( self->mCallbackUserdata ); - } -} - -// static -void LLTabContainer::onNextBtn( void* userdata ) +void LLTabContainer::onNextBtn( const LLSD& data ) { - // Scroll tabs to the left - LLTabContainer* self = (LLTabContainer*) userdata; - if (!self->mScrolled) + if (!mScrolled) { - self->scrollNext(); + scrollNext(); } - self->mScrolled = FALSE; + mScrolled = FALSE; } -// static -void LLTabContainer::onNextBtnHeld( void* userdata ) +void LLTabContainer::onNextBtnHeld( const LLSD& data ) { - LLTabContainer* self = (LLTabContainer*) userdata; - if (self->mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME) + if (mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME) { - self->mScrollTimer.reset(); - self->scrollNext(); - self->mScrolled = TRUE; + mScrollTimer.reset(); + scrollNext(); + mScrolled = TRUE; } } -// static -void LLTabContainer::onPrevBtn( void* userdata ) +void LLTabContainer::onPrevBtn( const LLSD& data ) { - LLTabContainer* self = (LLTabContainer*) userdata; - if (!self->mScrolled) + if (!mScrolled) { - self->scrollPrev(); + scrollPrev(); } - self->mScrolled = FALSE; + mScrolled = FALSE; } -// static -void LLTabContainer::onJumpFirstBtn( void* userdata ) +void LLTabContainer::onJumpFirstBtn( const LLSD& data ) { - LLTabContainer* self = (LLTabContainer*) userdata; - self->mScrollPos = 0; + mScrollPos = 0; } -// static -void LLTabContainer::onJumpLastBtn( void* userdata ) +void LLTabContainer::onJumpLastBtn( const LLSD& data ) { - LLTabContainer* self = (LLTabContainer*) userdata; - self->mScrollPos = self->mMaxScrollPos; + mScrollPos = mMaxScrollPos; } -// static -void LLTabContainer::onPrevBtnHeld( void* userdata ) +void LLTabContainer::onPrevBtnHeld( const LLSD& data ) { - LLTabContainer* self = (LLTabContainer*) userdata; - if (self->mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME) + if (mScrollTimer.getElapsedTimeF32() > SCROLL_STEP_TIME) { - self->mScrollTimer.reset(); - self->scrollPrev(); - self->mScrolled = TRUE; + mScrollTimer.reset(); + scrollPrev(); + mScrolled = TRUE; } } -// static -LLView* LLTabContainer::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory) -{ - std::string name("tab_container"); - node->getAttributeString("name", name); - - // Figure out if we are creating a vertical or horizontal tab container. - bool is_vertical = false; - LLTabContainer::TabPosition tab_position = LLTabContainer::TOP; - if (node->hasAttribute("tab_position")) - { - std::string tab_position_string; - node->getAttributeString("tab_position", tab_position_string); - LLStringUtil::toLower(tab_position_string); - - if ("top" == tab_position_string) - { - tab_position = LLTabContainer::TOP; - is_vertical = false; - } - else if ("bottom" == tab_position_string) - { - tab_position = LLTabContainer::BOTTOM; - is_vertical = false; - } - else if ("left" == tab_position_string) - { - is_vertical = true; - } - } - BOOL border = FALSE; - node->getAttributeBOOL("border", border); - - LLTabContainer* tab_container = new LLTabContainer(name, LLRect::null, tab_position, border, is_vertical); - - S32 tab_min_width = tab_container->mMinTabWidth; - if (node->hasAttribute("tab_width")) - { - node->getAttributeS32("tab_width", tab_min_width); - } - else if( node->hasAttribute("tab_min_width")) - { - node->getAttributeS32("tab_min_width", tab_min_width); - } - - S32 tab_max_width = tab_container->mMaxTabWidth; - if (node->hasAttribute("tab_max_width")) - { - node->getAttributeS32("tab_max_width", tab_max_width); - } - - tab_container->setMinTabWidth(tab_min_width); - tab_container->setMaxTabWidth(tab_max_width); - - BOOL hidden(tab_container->getTabsHidden()); - node->getAttributeBOOL("hide_tabs", hidden); - tab_container->setTabsHidden(hidden); - - tab_container->setPanelParameters(node, parent); - - if (LLFloater::getFloaterHost()) - { - LLFloater::getFloaterHost()->setTabContainer(tab_container); - } - - //parent->addChild(tab_container); - - // Add all tab panels. - LLXMLNodePtr child; - for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling()) - { - LLView *control = factory->createCtrlWidget(tab_container, child); - if (control && control->isPanel()) - { - LLPanel* panelp = (LLPanel*)control; - std::string label; - child->getAttributeString("label", label); - if (label.empty()) - { - label = panelp->getLabel(); - } - BOOL placeholder = FALSE; - child->getAttributeBOOL("placeholder", placeholder); - tab_container->addTabPanel(panelp, label, false, - NULL, NULL, 0, placeholder); - } - } - - tab_container->selectFirstTab(); - - tab_container->postBuild(); - - tab_container->initButtons(); // now that we have the correct rect - - return tab_container; -} - // private void LLTabContainer::initButtons() @@ -1591,99 +1524,105 @@ void LLTabContainer::initButtons() return; // Don't have a rect yet or already got called } - std::string out_id; - std::string in_id; - if (mIsVertical) { + static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0); // 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; + S32 btn_top_lower = getRect().mBottom+tabcntrv_arrow_btn_size; LLRect up_arrow_btn_rect; - up_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top, TABCNTRV_ARROW_BTN_SIZE, TABCNTRV_ARROW_BTN_SIZE ); + up_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top, tabcntrv_arrow_btn_size, tabcntrv_arrow_btn_size ); LLRect down_arrow_btn_rect; - down_arrow_btn_rect.setLeftTopAndSize( mMinTabWidth/2 , btn_top_lower, TABCNTRV_ARROW_BTN_SIZE, TABCNTRV_ARROW_BTN_SIZE ); - - out_id = "UIImgBtnScrollUpOutUUID"; - in_id = "UIImgBtnScrollUpInUUID"; - mPrevArrowBtn = new LLButton(std::string("Up Arrow"), up_arrow_btn_rect, - out_id, in_id, LLStringUtil::null, - &onPrevBtn, this, NULL ); - mPrevArrowBtn->setFollowsTop(); - mPrevArrowBtn->setFollowsLeft(); - - out_id = "UIImgBtnScrollDownOutUUID"; - in_id = "UIImgBtnScrollDownInUUID"; - mNextArrowBtn = new LLButton(std::string("Down Arrow"), down_arrow_btn_rect, - out_id, in_id, LLStringUtil::null, - &onNextBtn, this, NULL ); - mNextArrowBtn->setFollowsBottom(); - mNextArrowBtn->setFollowsLeft(); + 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); } else // Horizontal { + static LLUICachedControl<S32> tabcntr_arrow_btn_size ("UITabCntrArrowBtnSize", 0); S32 arrow_fudge = 1; // match new art better - // tabs on bottom reserve room for resize handle (just in case) - if (getTabPosition() == BOTTOM) - { - mRightTabBtnOffset = RESIZE_HANDLE_WIDTH; - } - // 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; + S32 btn_top = (getTabPosition() == TOP ) ? getRect().getHeight() - getTopBorderHeight() : tabcntr_arrow_btn_size + 1; 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, TABCNTR_ARROW_BTN_SIZE ); + left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1+tabcntr_arrow_btn_size, btn_top + arrow_fudge, tabcntr_arrow_btn_size, tabcntr_arrow_btn_size ); LLRect jump_left_arrow_btn_rect; - jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); + jump_left_arrow_btn_rect.setLeftTopAndSize( LLPANEL_BORDER_WIDTH+1, btn_top + arrow_fudge, tabcntr_arrow_btn_size, tabcntr_arrow_btn_size ); - S32 right_pad = TABCNTR_ARROW_BTN_SIZE + LLPANEL_BORDER_WIDTH + 1; + S32 right_pad = tabcntr_arrow_btn_size + LLPANEL_BORDER_WIDTH + 1; LLRect right_arrow_btn_rect; - right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad - TABCNTR_ARROW_BTN_SIZE, + right_arrow_btn_rect.setLeftTopAndSize( getRect().getWidth() - mRightTabBtnOffset - right_pad - tabcntr_arrow_btn_size, btn_top + arrow_fudge, - TABCNTR_ARROW_BTN_SIZE, TABCNTR_ARROW_BTN_SIZE ); + tabcntr_arrow_btn_size, tabcntr_arrow_btn_size ); 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, TABCNTR_ARROW_BTN_SIZE ); - - out_id = "UIImgBtnJumpLeftOutUUID"; - in_id = "UIImgBtnJumpLeftInUUID"; - mJumpPrevArrowBtn = new LLButton(std::string("Jump Left Arrow"), jump_left_arrow_btn_rect, - out_id, in_id, LLStringUtil::null, - &LLTabContainer::onJumpFirstBtn, this, LLFontGL::getFontSansSerif() ); - mJumpPrevArrowBtn->setFollowsLeft(); - - out_id = "UIImgBtnScrollLeftOutUUID"; - in_id = "UIImgBtnScrollLeftInUUID"; - mPrevArrowBtn = new LLButton(std::string("Left Arrow"), left_arrow_btn_rect, - out_id, in_id, LLStringUtil::null, - &LLTabContainer::onPrevBtn, this, LLFontGL::getFontSansSerif() ); - mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld); - mPrevArrowBtn->setFollowsLeft(); - - out_id = "UIImgBtnJumpRightOutUUID"; - in_id = "UIImgBtnJumpRightInUUID"; - mJumpNextArrowBtn = new LLButton(std::string("Jump Right Arrow"), jump_right_arrow_btn_rect, - out_id, in_id, LLStringUtil::null, - &LLTabContainer::onJumpLastBtn, this, - LLFontGL::getFontSansSerif()); - mJumpNextArrowBtn->setFollowsRight(); - - out_id = "UIImgBtnScrollRightOutUUID"; - in_id = "UIImgBtnScrollRightInUUID"; - mNextArrowBtn = new LLButton(std::string("Right Arrow"), right_arrow_btn_rect, - out_id, in_id, LLStringUtil::null, - &LLTabContainer::onNextBtn, this, - LLFontGL::getFontSansSerif()); - mNextArrowBtn->setFollowsRight(); + tabcntr_arrow_btn_size, tabcntr_arrow_btn_size ); + + 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); if( getTabPosition() == TOP ) { @@ -1701,12 +1640,10 @@ void LLTabContainer::initButtons() } } - mPrevArrowBtn->setHeldDownCallback(onPrevBtnHeld); mPrevArrowBtn->setSaveToXML(false); mPrevArrowBtn->setTabStop(FALSE); addChild(mPrevArrowBtn); - mNextArrowBtn->setHeldDownCallback(onNextBtnHeld); mNextArrowBtn->setSaveToXML(false); mNextArrowBtn->setTabStop(FALSE); addChild(mNextArrowBtn); @@ -1729,7 +1666,17 @@ void LLTabContainer::initButtons() setDefaultTabGroup(1); } -LLTabContainer::LLTabTuple* LLTabContainer::getTabByPanel(LLPanel* child) +//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) { for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { @@ -1775,14 +1722,16 @@ void LLTabContainer::insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_p void LLTabContainer::updateMaxScrollPos() { + static LLUICachedControl<S32> tabcntrv_pad ("UITabCntrvPad", 0); BOOL no_scroll = TRUE; if (mIsVertical) { - S32 tab_total_height = (BTN_HEIGHT + TABCNTRV_PAD) * getTabCount(); + S32 tab_total_height = (BTN_HEIGHT + tabcntrv_pad) * getTabCount(); S32 available_height = getRect().getHeight() - getTopBorderHeight(); if( tab_total_height > available_height ) { - S32 available_height_with_arrows = getRect().getHeight() - 2*(TABCNTRV_ARROW_BTN_SIZE + 3*TABCNTRV_PAD); + static LLUICachedControl<S32> tabcntrv_arrow_btn_size ("UITabCntrvArrowBtnSize", 0); + S32 available_height_with_arrows = getRect().getHeight() - 2*(tabcntrv_arrow_btn_size + 3*tabcntrv_pad); S32 additional_needed = tab_total_height - available_height_with_arrows; setMaxScrollPos((S32) ceil(additional_needed / float(BTN_HEIGHT) ) ); no_scroll = FALSE; @@ -1790,16 +1739,19 @@ void LLTabContainer::updateMaxScrollPos() } else { + static LLUICachedControl<S32> tabcntr_tab_h_pad ("UITabCntrTabHPad", 0); + static LLUICachedControl<S32> tabcntr_arrow_btn_size ("UITabCntrArrowBtnSize", 0); + static LLUICachedControl<S32> tabcntr_tab_partial_width ("UITabCntrTabPartialWidth", 0); S32 tab_space = 0; S32 available_space = 0; tab_space = mTotalTabWidth; - available_space = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_TAB_H_PAD); + available_space = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_tab_h_pad); if( tab_space > available_space ) { - S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + TABCNTR_ARROW_BTN_SIZE + TABCNTR_ARROW_BTN_SIZE + 1); + S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size + tabcntr_arrow_btn_size + 1); // subtract off reserved portion on left - available_width_with_arrows -= TABCNTR_TAB_PARTIAL_WIDTH; + available_width_with_arrows -= tabcntr_tab_partial_width; S32 running_tab_width = 0; setMaxScrollPos(getTabCount()); |