FIRE-2778: Allow re-arranging IM tabs; by Kitty Barnett (Catznip Viewer), with modifications for Firestorm
parent
ab7d3956f1
commit
79295f6a34
|
|
@ -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]
|
||||
|
||||
// <FS:ND> 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 );
|
||||
}
|
||||
// </FS:ND>
|
||||
// </FS:ND>
|
||||
|
|
|
|||
|
|
@ -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<LLTabContainer::TabPosition, TabPositions>
|
||||
|
|
@ -83,6 +89,9 @@ public:
|
|||
label_pad_left;
|
||||
|
||||
Optional<bool> hide_tabs;
|
||||
// [SL:KB] - Patch: UI-TabRearrange | Checked: 2010-06-05 (Catznip-3.3)
|
||||
Optional<bool> tab_allow_rearrange;
|
||||
// [/SL:KB]
|
||||
Optional<S32> tab_padding_right;
|
||||
|
||||
Optional<TabParams> 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); // <FS:LO> 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<void(S32, LLPanel*)> 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;
|
||||
|
|
|
|||
|
|
@ -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<LLFloater*>(tab_panel);
|
||||
if (!pIMFloater)
|
||||
return;
|
||||
|
||||
const LLUUID& idSession = pIMFloater->getKey().asUUID();
|
||||
if (idSession.isNull())
|
||||
return;
|
||||
|
||||
LLChicletPanel* pChicletPanel = LLChicletBar::instance().getChicletPanel();
|
||||
LLChiclet* pIMChiclet = pChicletPanel->findChiclet<LLChiclet>(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<LLIMChiclet>(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<LLIMChiclet*>(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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<LLChiclet*>(chiclet));
|
||||
arrange();
|
||||
}
|
||||
// [/SL:KB]
|
||||
|
||||
void LLChicletPanel::removeChiclet(LLChiclet*chiclet)
|
||||
{
|
||||
chiclet_list_t::iterator it = mChicletList.begin();
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue