Skip to content

Add drag-n-drop reordering for clothing layers#5918

Open
gwigz wants to merge 2 commits into
secondlife:developfrom
gwigz:gwigz/dnd-cof-layers
Open

Add drag-n-drop reordering for clothing layers#5918
gwigz wants to merge 2 commits into
secondlife:developfrom
gwigz:gwigz/dnd-cof-layers

Conversation

@gwigz

@gwigz gwigz commented Jun 11, 2026

Copy link
Copy Markdown

This also includes changes for scroll containers to preserve and restore scroll position during layout and resize. Without it, the scroll would jump and place the first selected item at the bottom of the scroll area, instead of holding position while the selection remained visible.

CleanShot.2026-06-11.at.9.19.51.mp4

- Drag-and-drop reordering for clothing layers with visual insertion indicator
- Scroll containers should also better preserve and restore scroll positions during layout and resize
@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@gwigz

gwigz commented Jun 11, 2026

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

mScrollbar[HORIZONTAL]->setDocSize( scrolled_rect.getWidth() );
mScrollbar[HORIZONTAL]->setPageSize( visible_width );
preserveScrollbarMetrics(VERTICAL, show_v_scrollbar, scrolled_rect.getHeight(), visible_height);
preserveScrollbarMetrics(HORIZONTAL, show_h_scrollbar, scrolled_rect.getWidth(), visible_width);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Floaters don't seem to have issues with resizes on reshape. Does it really need to call setDocPos? setDocPos issues callbacks as is.

{
mStoredDocPos[axis] = mScrollbar[axis]->getDocPos();
}
mScrollbar[axis]->setDocSize(doc_size);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function seems needlesly complicated. setDocSize already calls setDocPos(mDocPos), so does setPageSize(), neither seem to modify mDocPos unless maximum position changed. In theory this can result in 3 callbacks from setDocSize?


S32 border_width = getBorderWidth();
preserveScrollbarMetrics(VERTICAL, show_v_scrollbar, doc_height, visible_height);
preserveScrollbarMetrics(HORIZONTAL, show_h_scrollbar, doc_width, visible_width);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this might cause issues with some views, where user refreshes the list (like a different search request), and instead of the starting point will end up in the middle of nowhere because refreshing cleaned the list but did not reset the position?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth making it opt-in behavior? it's likely only COF that needs this to retain a nice UX when re-ordering

@gwigz gwigz Jun 15, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when COF reorder triggers a full refresh() (clear + repopulate), the clear zeroes the items-panel height, reshapes, hides the scroll, and zeroes itself here:

mScrollbar[VERTICAL]->setVisible( false );
mScrollbar[VERTICAL]->setDocPos( 0 );

refresh() saved & restored scroll, but it was one-shot, and a later re-layout re-ran updateScroll and wiped it.

the mStoredDocPos is an attempt to work over that at the container level, which is possibly too broad? tried at a higher level but you'd see the scroll jump to the top for a frame, some very fiddly logic around it.

@akleshchev akleshchev Jun 16, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

worth making it opt-in behavior?

Probably. It does make sense for position to persist that way, but not all lists going to need or want it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the mStoredDocPos is an attempt to work over that at the container level, which is possibly too broad?

While it is too broad in the sense that nothing else uses it, having optional position restoration on container level does make sense. But it would be fine to have it at cof level.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will take a shot at simplifying it

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds user-facing drag-and-drop reordering for worn clothing layers in the COF wearables UI, and updates scroll/reshape behavior so scroll position is preserved during layout changes (preventing selection-related “scroll jump” regressions).

Changes:

  • Adds drag-to-reorder support to LLFlatListView (drag arming, indicator drawing, constrained reordering, selection handling, callbacks).
  • Adds new appearance/wearables APIs to reorder clothing layers by absolute index or by an entire type-group order, persisting the new order to COF link descriptions.
  • Updates scroll container behavior to preserve/restore scroll position during reshape/updateScroll, and adds a tooltip string for reorderable clothing rows.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
indra/newview/skins/default/xui/en/strings.xml Adds tooltip string for reorderable clothing rows.
indra/newview/skins/default/xui/en/panel_cof_wearables.xml Enables reordering on the clothing flat_list_view.
indra/newview/llcofwearables.h Declares callbacks to validate and apply clothing reordering.
indra/newview/llcofwearables.cpp Hooks list reorder callbacks and persists per-type ordering after a drag.
indra/newview/llappearancemgr.h Introduces reorderWearable* APIs and internal persistence helper.
indra/newview/llappearancemgr.cpp Implements single-item and group reordering and persists ordering via COF link descriptions.
indra/newview/llagentwearables.h Adds moveWearableToIndex() for absolute layer moves.
indra/newview/llagentwearables.cpp Improves wearable-index lookup and implements move-to-index via swaps.
indra/llui/llscrollcontainer.h Adds stored doc positions and helper for preserving scrollbar metrics.
indra/llui/llscrollcontainer.cpp Preserves/restores scrollbar doc position across reshape/updateScroll to prevent jumping.
indra/llui/llflatlistview.h Adds reorder params, callbacks, and drag state for reorderable lists.
indra/llui/llflatlistview.cpp Implements drag-to-reorder behavior, indicator rendering, and selection deferral logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread indra/newview/skins/default/xui/en/strings.xml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add drag-n-drop reordering for clothing layers

3 participants