Skip to content

Commit 7963260

Browse files
authored
Merge pull request #329 from gwigz/gwigz/cof-dnd-updates
Port clothing layer drag-and-drop refinements
2 parents d2546ef + db325e0 commit 7963260

8 files changed

Lines changed: 211 additions & 69 deletions

File tree

indra/llui/llflatlistview.cpp

Lines changed: 123 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ bool LLFlatListView::addItem(LLPanel * item, const LLSD& value /*= LLUUID::null*
110110
}
111111

112112
//_4 is for MASK
113-
item->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
113+
item->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4, CLICK_LEFT));
114114
item->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, new_pair, _4));
115115

116116
// Children don't accept the focus
@@ -168,7 +168,7 @@ bool LLFlatListView::addItemPairs(pairs_list_t panel_list, bool rearrange /*= tr
168168
mItemsPanel->addChild(panel);
169169

170170
//_4 is for MASK
171-
panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
171+
panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4, CLICK_LEFT));
172172
panel->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, new_pair, _4));
173173
// Children don't accept the focus
174174
panel->setTabStop(false);
@@ -195,7 +195,7 @@ bool LLFlatListView::addItemPairs(pairs_list_t panel_list, bool rearrange /*= tr
195195
mItemsPanel->addChild(panel);
196196

197197
//_4 is for MASK
198-
panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, item_pair, _4));
198+
panel->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, item_pair, _4, CLICK_LEFT));
199199
panel->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, item_pair, _4));
200200
// Children don't accept the focus
201201
panel->setTabStop(false);
@@ -247,7 +247,7 @@ bool LLFlatListView::insertItemAfter(LLPanel* after_item, LLPanel* item_to_add,
247247
}
248248

249249
//_4 is for MASK
250-
item_to_add->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4));
250+
item_to_add->setMouseDownCallback(boost::bind(&LLFlatListView::onItemMouseClick, this, new_pair, _4, CLICK_LEFT));
251251
item_to_add->setRightMouseDownCallback(boost::bind(&LLFlatListView::onItemRightMouseClick, this, new_pair, _4));
252252

253253
rearrangeItems();
@@ -504,9 +504,8 @@ LLFlatListView::LLFlatListView(const LLFlatListView::Params& p)
504504
, mFocusOnItemClicked(true)
505505
, mAllowReorder(p.allow_reorder)
506506
, mIsReordering(false)
507-
, mProcessingRightClick(false)
508-
, mReorderDragPair(NULL)
509-
, mDeferredSelectPair(NULL)
507+
, mReorderDragPair(nullptr)
508+
, mDeferredSelectPair(nullptr)
510509
, mReorderMouseDownX(0)
511510
, mReorderMouseDownY(0)
512511
, mReorderInsertIndex(-1)
@@ -672,7 +671,7 @@ void LLFlatListView::rearrangeItems()
672671
mSelectedItemsBorder->setRect(getLastSelectedItemRect().stretch(-1));
673672
}
674673

675-
void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
674+
void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask, EMouseClickType clicktype)
676675
{
677676
if (!item_pair) return;
678677

@@ -687,7 +686,7 @@ void LLFlatListView::onItemMouseClick(item_pair_t* item_pair, MASK mask)
687686
setFocus(true);
688687
}
689688

690-
if (!(mask & (MASK_SHIFT | MASK_CONTROL)))
689+
if (clicktype == CLICK_LEFT && !(mask & (MASK_SHIFT | MASK_CONTROL)))
691690
{
692691
armReorderDrag(item_pair);
693692
}
@@ -801,16 +800,14 @@ void LLFlatListView::onItemRightMouseClick(item_pair_t* item_pair, MASK mask)
801800
return;
802801

803802
// else got same behavior as at onItemMouseClick, but a right click must never start a drag
804-
mProcessingRightClick = true;
805-
onItemMouseClick(item_pair, mask);
806-
mProcessingRightClick = false;
803+
onItemMouseClick(item_pair, mask, CLICK_RIGHT);
807804
}
808805

809-
static const S32 REORDER_DRAG_THRESHOLD = 5;
806+
static constexpr S32 REORDER_DRAG_THRESHOLD = 5;
810807

811808
void LLFlatListView::armReorderDrag(item_pair_t* item_pair)
812809
{
813-
if (!mAllowReorder || mProcessingRightClick)
810+
if (!mAllowReorder)
814811
{
815812
return;
816813
}
@@ -832,7 +829,7 @@ void LLFlatListView::armReorderDrag(item_pair_t* item_pair)
832829

833830
mReorderDragPair = item_pair;
834831
mReorderDragGroup.clear();
835-
mDeferredSelectPair = NULL;
832+
mDeferredSelectPair = nullptr;
836833
mIsReordering = false;
837834
mReorderInsertIndex = -1;
838835

@@ -842,7 +839,8 @@ void LLFlatListView::armReorderDrag(item_pair_t* item_pair)
842839

843840
void LLFlatListView::updateReorderDrag(S32 x, S32 y)
844841
{
845-
if (!mReorderDragPair) return;
842+
if (!mReorderDragPair)
843+
return;
846844

847845
if (!mIsReordering)
848846
{
@@ -866,7 +864,8 @@ void LLFlatListView::buildReorderGroup()
866864

867865
for (item_pair_t* pair : mItemPairs)
868866
{
869-
if (!pair->first->getVisible()) continue;
867+
if (!pair->first->getVisible())
868+
continue;
870869

871870
if (pair == mReorderDragPair)
872871
{
@@ -891,7 +890,8 @@ void LLFlatListView::getReorderRemaining(pairs_list_t& remaining) const
891890
remaining.clear();
892891
for (item_pair_t* pair : mItemPairs)
893892
{
894-
if (!pair->first->getVisible() || isInReorderGroup(pair)) continue;
893+
if (!pair->first->getVisible() || isInReorderGroup(pair))
894+
continue;
895895
remaining.push_back(pair);
896896
}
897897
}
@@ -903,12 +903,16 @@ void LLFlatListView::finishReorderDrag()
903903
pairs_list_t remaining;
904904
getReorderRemaining(remaining);
905905

906-
// Resolve the drop boundary to the remaining row it lands before (NULL = append).
907-
item_pair_t* anchor = NULL;
906+
// Resolve the drop boundary to the remaining row it lands before (nullptr = append).
907+
item_pair_t* anchor = nullptr;
908908
S32 cur = 0;
909909
for (item_pair_t* pair : remaining)
910910
{
911-
if (cur == mReorderInsertIndex) { anchor = pair; break; }
911+
if (cur == mReorderInsertIndex)
912+
{
913+
anchor = pair;
914+
break;
915+
}
912916
++cur;
913917
}
914918

@@ -919,7 +923,7 @@ void LLFlatListView::finishReorderDrag()
919923
mItemPairs.remove(pair);
920924
}
921925

922-
pairs_iterator_t it = (anchor != NULL)
926+
pairs_iterator_t it = (anchor != nullptr)
923927
? std::find(mItemPairs.begin(), mItemPairs.end(), anchor)
924928
: mItemPairs.end();
925929
for (item_pair_t* pair : mReorderDragGroup)
@@ -931,7 +935,17 @@ void LLFlatListView::finishReorderDrag()
931935

932936
if (mReorderCallback)
933937
{
934-
mReorderCallback(moved_value, mReorderInsertIndex);
938+
S32 visible_index = 0;
939+
for (item_pair_t* pair : mItemPairs)
940+
{
941+
if (!pair->first->getVisible())
942+
continue;
943+
if (pair == mReorderDragPair)
944+
break;
945+
++visible_index;
946+
}
947+
948+
mReorderCallback(moved_value, visible_index);
935949
}
936950
}
937951

@@ -942,7 +956,7 @@ void LLFlatListView::cancelReorderDrag()
942956
{
943957
if (hasMouseCapture())
944958
{
945-
gFocusMgr.setMouseCapture(NULL);
959+
gFocusMgr.setMouseCapture(nullptr);
946960
}
947961

948962
clearReorderDragState();
@@ -954,18 +968,36 @@ void LLFlatListView::clearReorderDragState()
954968
{
955969
getWindow()->setCursor(UI_CURSOR_ARROW);
956970
}
957-
mReorderDragPair = NULL;
971+
972+
bool was_armed = (mReorderDragPair != nullptr);
973+
974+
mReorderDragPair = nullptr;
958975
mReorderDragGroup.clear();
959-
mDeferredSelectPair = NULL;
976+
mDeferredSelectPair = nullptr;
960977
mIsReordering = false;
961978
mReorderInsertIndex = -1;
979+
980+
if (was_armed && mReorderEndedCallback)
981+
{
982+
mReorderEndedCallback();
983+
}
962984
}
963985

964986
void LLFlatListView::onMouseCaptureLost()
965987
{
966988
clearReorderDragState();
967989
}
968990

991+
void LLFlatListView::onVisibilityChange(bool new_visibility)
992+
{
993+
if (!new_visibility && mReorderDragPair)
994+
{
995+
cancelReorderDrag();
996+
}
997+
998+
LLScrollContainer::onVisibilityChange(new_visibility);
999+
}
1000+
9691001
S32 LLFlatListView::getInsertIndexAt(S32 x, S32 y) const
9701002
{
9711003
S32 panel_x, panel_y;
@@ -976,7 +1008,8 @@ S32 LLFlatListView::getInsertIndexAt(S32 x, S32 y) const
9761008
S32 index = 0;
9771009
for (item_pair_t* pair : mItemPairs)
9781010
{
979-
if (!pair->first->getVisible() || isInReorderGroup(pair)) continue;
1011+
if (!pair->first->getVisible() || isInReorderGroup(pair))
1012+
continue;
9801013

9811014
if (pair->first->getRect().getCenterY() > panel_y)
9821015
{
@@ -986,9 +1019,31 @@ S32 LLFlatListView::getInsertIndexAt(S32 x, S32 y) const
9861019
return index;
9871020
}
9881021

1022+
LLFlatListView::item_pair_t* LLFlatListView::getReorderPairAt(S32 x, S32 y) const
1023+
{
1024+
S32 panel_x, panel_y;
1025+
localPointToOtherView(x, y, &panel_x, &panel_y, mItemsPanel);
1026+
1027+
for (item_pair_t* pair : mItemPairs)
1028+
{
1029+
if (!pair->first->getVisible())
1030+
continue;
1031+
1032+
// Claim the padding above each row so gap presses still resolve to a row.
1033+
LLRect rc = pair->first->getRect();
1034+
rc.mTop += mItemPad;
1035+
if (rc.pointInRect(panel_x, panel_y))
1036+
{
1037+
return pair;
1038+
}
1039+
}
1040+
return nullptr;
1041+
}
1042+
9891043
S32 LLFlatListView::constrainInsertIndex(S32 dest_index) const
9901044
{
991-
if (!mReorderValidateCallback) return dest_index;
1045+
if (!mReorderValidateCallback)
1046+
return dest_index;
9921047

9931048
// Clamp the boundary to the contiguous run of remaining rows that share the
9941049
// grabbed row's group, so a drag can't leave its group.
@@ -1003,24 +1058,29 @@ S32 LLFlatListView::constrainInsertIndex(S32 dest_index) const
10031058
{
10041059
if (mReorderValidateCallback(dragged, pair->second))
10051060
{
1006-
if (first_valid < 0) first_valid = i;
1061+
if (first_valid < 0)
1062+
first_valid = i;
10071063
last_valid = i;
10081064
}
10091065
++i;
10101066
}
10111067

1012-
if (first_valid < 0) return -1; // no valid neighbour (whole group is being dragged)
1068+
if (first_valid < 0)
1069+
return -1; // no valid neighbour (whole group is being dragged)
10131070

1014-
if (dest_index < first_valid) return first_valid;
1015-
if (dest_index > last_valid + 1) return last_valid + 1;
1071+
if (dest_index < first_valid)
1072+
return first_valid;
1073+
if (dest_index > last_valid + 1)
1074+
return last_valid + 1;
10161075
return dest_index;
10171076
}
10181077

10191078
void LLFlatListView::drawReorderIndicator()
10201079
{
10211080
pairs_list_t remaining;
10221081
getReorderRemaining(remaining);
1023-
if (remaining.empty()) return;
1082+
if (remaining.empty())
1083+
return;
10241084

10251085
const LLRect& panel_rc = mItemsPanel->getRect();
10261086
const LLColor4& color = mDragIndicatorColor.get();
@@ -1039,21 +1099,27 @@ void LLFlatListView::drawReorderIndicator()
10391099
bool at_end = mReorderInsertIndex >= count;
10401100
S32 anchor_idx = at_end ? count - 1 : mReorderInsertIndex;
10411101

1042-
item_pair_t* anchor = NULL;
1102+
item_pair_t* anchor = nullptr;
10431103
S32 cur = 0;
10441104
for (item_pair_t* pair : remaining)
10451105
{
1046-
if (cur == anchor_idx) { anchor = pair; break; }
1106+
if (cur == anchor_idx)
1107+
{
1108+
anchor = pair;
1109+
break;
1110+
}
10471111
++cur;
10481112
}
1049-
if (!anchor) return;
1113+
if (!anchor)
1114+
return;
10501115

10511116
const LLRect& item_rc = anchor->first->getRect();
10521117
S32 left = panel_rc.mLeft + item_rc.mLeft;
10531118
S32 right = panel_rc.mLeft + item_rc.mRight;
10541119
S32 line_y = panel_rc.mBottom + (at_end ? item_rc.mBottom : item_rc.mTop);
10551120

1056-
if (line_y < 0 || line_y > getRect().getHeight()) return;
1121+
if (line_y < 0 || line_y > getRect().getHeight())
1122+
return;
10571123

10581124
gl_rect_2d(left, line_y, right, line_y - 1, color, true);
10591125
}
@@ -1072,13 +1138,31 @@ bool LLFlatListView::handleHover(S32 x, S32 y, MASK mask)
10721138
return LLScrollContainer::handleHover(x, y, mask);
10731139
}
10741140

1141+
bool LLFlatListView::handleMouseDown(S32 x, S32 y, MASK mask)
1142+
{
1143+
bool handled = LLScrollContainer::handleMouseDown(x, y, mask);
1144+
1145+
// A press in the padding between rows misses every item, so the per-item
1146+
// mouse-down never arms a reorder. Map it to the nearest row and arm there;
1147+
// armReorderDrag's capture guard ignores presses a child control already took.
1148+
if (mAllowReorder && !mReorderDragPair && !(mask & (MASK_CONTROL | MASK_SHIFT)))
1149+
{
1150+
if (item_pair_t* pair = getReorderPairAt(x, y))
1151+
{
1152+
onItemMouseClick(pair, mask, CLICK_LEFT);
1153+
}
1154+
}
1155+
1156+
return handled || (mReorderDragPair != nullptr);
1157+
}
1158+
10751159
bool LLFlatListView::handleMouseUp(S32 x, S32 y, MASK mask)
10761160
{
10771161
if (mReorderDragPair && hasMouseCapture())
10781162
{
10791163
bool was_reordering = mIsReordering;
10801164
item_pair_t* deferred = mDeferredSelectPair;
1081-
mDeferredSelectPair = NULL;
1165+
mDeferredSelectPair = nullptr;
10821166

10831167
finishReorderDrag();
10841168

@@ -1475,7 +1559,7 @@ bool LLFlatListView::removeItemPair(item_pair_t* item_pair, bool rearrange)
14751559
}
14761560
if (item_pair == mDeferredSelectPair)
14771561
{
1478-
mDeferredSelectPair = NULL;
1562+
mDeferredSelectPair = nullptr;
14791563
}
14801564

14811565
bool deleted = false;

0 commit comments

Comments
 (0)