diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 3dee8ce989..7d8438a853 100755 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -214,6 +214,9 @@ LLTabContainer::Params::Params() label_pad_left("label_pad_left"), tab_position("tab_position"), hide_tabs("hide_tabs", false), +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2010-06-05 (Catznip-3.3) + tab_allow_rearrange("tab_allow_rearrange", false), +// [/SL:KB] tab_padding_right("tab_padding_right"), first_tab("first_tab"), middle_tab("middle_tab"), @@ -230,6 +233,10 @@ LLTabContainer::LLTabContainer(const LLTabContainer::Params& p) : LLPanel(p), mCurrentTabIdx(-1), mTabsHidden(p.hide_tabs), +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3) + mAllowRearrange(p.tab_allow_rearrange), + mRearrangeSignal(NULL), +// [/SL:KB] mScrolled(FALSE), mScrollPos(0), mScrollPosPixels(0), @@ -304,6 +311,10 @@ LLTabContainer::~LLTabContainer() { std::for_each(mTabList.begin(), mTabList.end(), DeletePointer()); mTabList.clear(); + +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3) + delete mRearrangeSignal; +// [/SL:KB] } //virtual @@ -623,11 +634,20 @@ BOOL LLTabContainer::handleMouseDown( S32 x, S32 y, MASK mask ) } if( tab_rect.pointInRect( x, y ) ) { - S32 index = getCurrentPanelIndex(); - index = llclamp(index, 0, tab_count-1); - LLButton* tab_button = getTab(index)->mButton; +// S32 index = getCurrentPanelIndex(); +// index = llclamp(index, 0, tab_count-1); +// LLButton* tab_button = getTab(index)->mButton; gFocusMgr.setMouseCapture(this); - tab_button->setFocus(TRUE); +// tab_button->setFocus(TRUE); +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2010-06-05 (Catznip-2.0) + // Only set keyboard focus to the tab button of the active panel (if we have one) if the user actually clicked on it + if (mCurrentTabIdx >= 0) + { + LLButton* pActiveTabBtn = mTabList[mCurrentTabIdx]->mButton; + if (pActiveTabBtn->pointInView(x - pActiveTabBtn->getRect().mLeft, y - pActiveTabBtn->getRect().mBottom)) + pActiveTabBtn->setFocus(TRUE); + } +// [/SL:KB] } } if (handled) { @@ -825,6 +845,12 @@ BOOL LLTabContainer::handleToolTip( S32 x, S32 y, MASK mask) // virtual BOOL LLTabContainer::handleKeyHere(KEY key, MASK mask) { +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2010-06-05 (Catznip-2.0) + if ( (mAllowRearrange) && (hasMouseCapture()) ) + { + return FALSE; // Don't process movement keys while the user might be rearranging tabs + } +// [/SL:KB] BOOL handled = FALSE; if (key == KEY_LEFT && mask == MASK_ALT) { @@ -925,27 +951,43 @@ BOOL LLTabContainer::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDrag { if (mJumpPrevArrowBtn && mJumpPrevArrowBtn->getRect().pointInRect(x, y)) { - S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; - mJumpPrevArrowBtn->handleHover(local_x, local_y, mask); +// [SL:KB] - Patch: Control-TabContainer | Checked: 2014-03-17 (Catznip-3.6) + mJumpPrevArrowBtn->onCommit(); + mDragAndDropDelayTimer.reset(); +// [/SL:KB] +// S32 local_x = x - mJumpPrevArrowBtn->getRect().mLeft; +// S32 local_y = y - mJumpPrevArrowBtn->getRect().mBottom; +// mJumpPrevArrowBtn->handleHover(local_x, local_y, mask); } if (mJumpNextArrowBtn && mJumpNextArrowBtn->getRect().pointInRect(x, y)) { - S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; - S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; - mJumpNextArrowBtn->handleHover(local_x, local_y, mask); +// [SL:KB] - Patch: Control-TabContainer | Checked: 2014-03-17 (Catznip-3.6) + mJumpNextArrowBtn->onCommit(); + mDragAndDropDelayTimer.reset(); +// [/SL:KB] +// S32 local_x = x - mJumpNextArrowBtn->getRect().mLeft; +// S32 local_y = y - mJumpNextArrowBtn->getRect().mBottom; +// mJumpNextArrowBtn->handleHover(local_x, local_y, mask); } if (mPrevArrowBtn->getRect().pointInRect(x, y)) { - S32 local_x = x - mPrevArrowBtn->getRect().mLeft; - S32 local_y = y - mPrevArrowBtn->getRect().mBottom; - mPrevArrowBtn->handleHover(local_x, local_y, mask); +// [SL:KB] - Patch: Control-TabContainer | Checked: 2014-03-17 (Catznip-3.6) + mPrevArrowBtn->onCommit(); + mDragAndDropDelayTimer.reset(); +// [/SL:KB] +// S32 local_x = x - mPrevArrowBtn->getRect().mLeft; +// S32 local_y = y - mPrevArrowBtn->getRect().mBottom; +// mPrevArrowBtn->handleHover(local_x, local_y, mask); } else if (mNextArrowBtn->getRect().pointInRect(x, y)) { - S32 local_x = x - mNextArrowBtn->getRect().mLeft; - S32 local_y = y - mNextArrowBtn->getRect().mBottom; - mNextArrowBtn->handleHover(local_x, local_y, mask); +// [SL:KB] - Patch: Control-TabContainer | Checked: 2014-03-17 (Catznip-3.6) + mNextArrowBtn->onCommit(); + mDragAndDropDelayTimer.reset(); +// [/SL:KB] +// S32 local_x = x - mNextArrowBtn->getRect().mLeft; +// S32 local_y = y - mNextArrowBtn->getRect().mBottom; +// mNextArrowBtn->handleHover(local_x, local_y, mask); } } @@ -2199,9 +2241,21 @@ void LLTabContainer::insertTuple(LLTabTuple * tuple, eInsertionPoint insertion_p mTabList.insert(current_iter, tuple); } break; +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-06-22 (Catznip-3.3) case END: - default: mTabList.push_back( tuple ); + break; + // All of the pre-defined insertion points are negative so if we encounter a positive number, assume it's an index + default: + S32 idxInsertion = (S32)insertion_point; + if ( (idxInsertion >= 0) && (idxInsertion < mTabList.size()) ) + mTabList.insert(mTabList.begin() + llmax(mLockedTabCount, idxInsertion), tuple); + else + mTabList.push_back(tuple); +// [/SL:KB] +// case END: +// default: +// mTabList.push_back( tuple ); } } @@ -2278,7 +2332,48 @@ void LLTabContainer::commitHoveredButton(S32 x, S32 y) S32 local_y = y - tuple->mButton->getRect().mBottom; if (tuple->mButton->pointInView(local_x, local_y) && tuple->mButton->getEnabled() && !tuple->mTabPanel->getVisible()) { - tuple->mButton->onCommit(); +// tuple->mButton->onCommit(); +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2010-06-05 (Catznip-2.5) + if ( (mAllowRearrange) && (mCurrentTabIdx >= 0) && (mTabList[mCurrentTabIdx]->mButton->hasFocus()) ) + { + S32 idxHover = iter - mTabList.begin(); + if ( (mCurrentTabIdx >= mLockedTabCount) && (idxHover >= mLockedTabCount) && (mCurrentTabIdx != idxHover) ) + { + LLRect rctCurTab = mTabList[mCurrentTabIdx]->mButton->getRect(); + LLRect rctHoverTab = mTabList[idxHover]->mButton->getRect(); + + // Only rearrange the tabs if the mouse pointer has cleared the overlap area + bool fClearedOverlap = + (mIsVertical) + ? ( (idxHover < mCurrentTabIdx) && (y > rctHoverTab.mTop - rctCurTab.getHeight()) ) || + ( (idxHover > mCurrentTabIdx) && (y < rctCurTab.mTop - rctHoverTab.getHeight()) ) + : ( (idxHover < mCurrentTabIdx) && (x < rctHoverTab.mLeft + rctCurTab.getWidth()) ) || + ( (idxHover > mCurrentTabIdx) && (x > rctCurTab.mLeft + rctHoverTab.getWidth()) ); + if (fClearedOverlap) + { + tuple = mTabList[mCurrentTabIdx]; + + mTabList.erase(mTabList.begin() + mCurrentTabIdx); + mTabList.insert(mTabList.begin() + idxHover, tuple); + + if (mRearrangeSignal) + (*mRearrangeSignal)(idxHover, tuple->mTabPanel); + + tuple->mButton->onCommit(); + tuple->mButton->setFocus(TRUE); + } + } + } + else + { + tuple->mButton->onCommit(); + tuple->mButton->setFocus(TRUE); +// [SL:KB] - Patch: Control-TabContainer | Checked: 2012-08-10 (Catznip-3.3) + return; +// [/SL:KB] + } + break; +// [/SL:KB] } } } @@ -2289,6 +2384,15 @@ S32 LLTabContainer::getTotalTabWidth() const return mTotalTabWidth; } +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3) +boost::signals2::connection LLTabContainer::setRearrangeCallback(const tab_rearrange_signal_t::slot_type& cb) +{ + if (!mRearrangeSignal) + mRearrangeSignal = new tab_rearrange_signal_t(); + return mRearrangeSignal->connect(cb); +} +// [/SL:KB] + // Hide one tab. Will switch to the first visible tab if one exists. Otherwise the Tabcontainer is hidden void LLTabContainer::setTabVisibility( LLPanel const *aPanel, bool aVisible ) { @@ -2319,4 +2423,4 @@ void LLTabContainer::setTabVisibility( LLPanel const *aPanel, bool aVisible ) else this->setVisible( FALSE ); } -// \ No newline at end of file +// diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 189d792024..7597033dc7 100755 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -46,10 +46,16 @@ public: }; typedef enum e_insertion_point { - START, - END, - LEFT_OF_CURRENT, - RIGHT_OF_CURRENT +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-06-22 (Catznip-3.3) + START = -1, + END = -2, + LEFT_OF_CURRENT = -3, + RIGHT_OF_CURRENT = -4 +// [/SL:KB] +// START, +// END, +// LEFT_OF_CURRENT, +// RIGHT_OF_CURRENT } eInsertionPoint; struct TabPositions : public LLInitParam::TypeValuesHelper @@ -83,6 +89,9 @@ public: label_pad_left; Optional hide_tabs; +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2010-06-05 (Catznip-3.3) + Optional tab_allow_rearrange; +// [/SL:KB] Optional tab_padding_right; Optional first_tab, @@ -140,9 +149,11 @@ public: /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); /*virtual*/ BOOL handleHover( S32 x, S32 y, MASK mask ); /*virtual*/ BOOL handleMouseUp( S32 x, S32 y, MASK mask ); +// [SL:KB] - Patch: Control-TabContainer | Checked: 2014-04-06 (Catznip-3.6) + /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); +// [/SL:KB] /*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleKeyHere(KEY key, MASK mask); - /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); // FIRE-8024 Ability to scroll tab containers with the scroll wheel on the mouse /*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType type, void* cargo_data, EAcceptance* accept, std::string& tooltip); @@ -234,6 +245,14 @@ public: void onJumpFirstBtn( const LLSD& data ); void onJumpLastBtn( const LLSD& data ); +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3) + void setAllowRearrange(bool enable) { mAllowRearrange = enable; } + bool getAllowRearrange() const { return mAllowRearrange; } + + typedef boost::signals2::signal tab_rearrange_signal_t; + boost::signals2::connection setRearrangeCallback(const tab_rearrange_signal_t::slot_type& cb); +// [/SL:KB] + private: void initButtons(); @@ -271,6 +290,10 @@ private: S32 mCurrentTabIdx; BOOL mTabsHidden; +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3) + bool mAllowRearrange; + tab_rearrange_signal_t* mRearrangeSignal; +// [/SL:KB] BOOL mScrolled; LLFrameTimer mScrollTimer; diff --git a/indra/newview/fsfloaterimcontainer.cpp b/indra/newview/fsfloaterimcontainer.cpp index db7ef1849e..a09aad3679 100644 --- a/indra/newview/fsfloaterimcontainer.cpp +++ b/indra/newview/fsfloaterimcontainer.cpp @@ -43,6 +43,8 @@ #include "fsfloaterim.h" #include "llvoiceclient.h" #include "lltoolbarview.h" +#include "llchiclet.h" +#include "llchicletbar.h" static const F32 VOICE_STATUS_UPDATE_INTERVAL = 1.0f; @@ -79,6 +81,9 @@ BOOL FSFloaterIMContainer::postBuild() // Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button // mTabContainer will be initialized in LLMultiFloater::addChild() + mTabContainer->setAllowRearrange(true); + mTabContainer->setRearrangeCallback(boost::bind(&FSFloaterIMContainer::onIMTabRearrange, this, _1, _2)); + mActiveVoiceUpdateTimer.setTimerExpirySec(VOICE_STATUS_UPDATE_INTERVAL); mActiveVoiceUpdateTimer.start(); @@ -139,6 +144,23 @@ void FSFloaterIMContainer::initTabs() } } +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3.0) +void FSFloaterIMContainer::onIMTabRearrange(S32 tab_index, LLPanel* tab_panel) +{ + LLFloater* pIMFloater = dynamic_cast(tab_panel); + if (!pIMFloater) + return; + + const LLUUID& idSession = pIMFloater->getKey().asUUID(); + if (idSession.isNull()) + return; + + LLChicletPanel* pChicletPanel = LLChicletBar::instance().getChicletPanel(); + LLChiclet* pIMChiclet = pChicletPanel->findChiclet(idSession); + pChicletPanel->setChicletIndex(pIMChiclet, tab_index - mTabContainer->getNumLockedTabs()); +} +// [/SL:KB] + void FSFloaterIMContainer::onOpen(const LLSD& key) { LLMultiFloater::onOpen(key); @@ -198,6 +220,39 @@ void FSFloaterIMContainer::addFloater(LLFloater* floaterp, floaterp->setCanClose(FALSE); return; } + else + { +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-06-22 (Catznip-3.3.0) + // If we're redocking a torn off IM floater, return it back to its previous place + if ( (floaterp->isTornOff()) && (LLTabContainer::END == insertion_point) ) + { + LLChicletPanel* pChicletPanel = LLChicletBar::instance().getChicletPanel(); + + LLIMChiclet* pChiclet = pChicletPanel->findChiclet(floaterp->getKey()); + S32 idxChiclet = pChicletPanel->getChicletIndex(pChiclet); + if ( (idxChiclet > 0) && (idxChiclet < pChicletPanel->getChicletCount()) ) + { + // Look for the first IM session to the left of this one + while (--idxChiclet >= 0) + { + if (pChiclet = dynamic_cast(pChicletPanel->getChiclet(idxChiclet))) + { + FSFloaterIM* pFloater = FSFloaterIM::findInstance(pChiclet->getSessionId()); + if (pFloater) + { + insertion_point = (LLTabContainer::eInsertionPoint)(mTabContainer->getIndexForPanel(pFloater) + 1); + break; + } + } + } + } + else + { + insertion_point = (0 == idxChiclet) ? LLTabContainer::START : LLTabContainer::END; + } + } +// [/SL:KB] + } LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point); diff --git a/indra/newview/fsfloaterimcontainer.h b/indra/newview/fsfloaterimcontainer.h index eef05dd552..4ece37dfed 100644 --- a/indra/newview/fsfloaterimcontainer.h +++ b/indra/newview/fsfloaterimcontainer.h @@ -103,6 +103,12 @@ private: void checkFlashing(); uuid_vec_t mFlashingSessions; + +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3.0) +protected: + void onIMTabRearrange(S32 tab_index, LLPanel* tab_panel); +// [/SL:KB] + }; #endif // FS_FLOATERIMCONTAINER_H diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp index 43310bbe11..b4a8d42832 100755 --- a/indra/newview/llchiclet.cpp +++ b/indra/newview/llchiclet.cpp @@ -1336,6 +1336,22 @@ S32 LLChicletPanel::getChicletIndex(const LLChiclet* chiclet) return -1; } +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3.0) +void LLChicletPanel::setChicletIndex(const LLChiclet* chiclet, S32 index) +{ + if ( (index >= mChicletList.size()) || (index < 0) ) + return; + + S32 cur_index = getChicletIndex(chiclet); + if ( (-1 == cur_index) && (cur_index != index) ) + return; + + mChicletList.erase(mChicletList.begin() + cur_index); + mChicletList.insert(mChicletList.begin() + index, const_cast(chiclet)); + arrange(); +} +// [/SL:KB] + void LLChicletPanel::removeChiclet(LLChiclet*chiclet) { chiclet_list_t::iterator it = mChicletList.begin(); diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h index b301595875..49dd94994f 100755 --- a/indra/newview/llchiclet.h +++ b/indra/newview/llchiclet.h @@ -1046,6 +1046,13 @@ public: */ S32 getChicletIndex(const LLChiclet* chiclet); +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3.0) + /** + * Sets the index of the specified chiclet in the list. + */ + void setChicletIndex(const LLChiclet* chiclet, S32 index); +// [/SL:KB] + /** * Removes chiclet by index. */