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.
*/