BListView: Add ScrollTo(index) method, auto-scroll on drag

Multi-select lists may also auto-scroll on drag now as well.

Document ScrollTo(index). Give Scrolling its own section.

Change-Id: I36284a28376a01bafd23ddb30162fc786fb41521
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7213
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk>
This commit is contained in:
John Scipione 2023-12-22 08:59:31 -05:00 committed by waddlesplash
parent 8d024b7062
commit 82bfaa954d
3 changed files with 69 additions and 21 deletions

View File

@ -461,6 +461,14 @@
*/
/*!
\name Scrolling
*/
//! @{
/*!
\fn void BListView::ScrollTo(BPoint point)
\brief Scroll the view to the specified \a point.
@ -473,6 +481,30 @@
*/
/*!
\fn void BListView::ScrollTo(int32 index)
\brief Scrolls to list item at \a index.
If above top scroll to first item, if below bottom
scroll to last item otherwise scroll to item at \a index.
\see IndexOf(), MouseMoved(), ScrollToSelection()
\since Haiku R1
*/
/*!
\fn void BListView::ScrollToSelection()
\brief Scrolls to selected list item.
\since BeOS R3
*/
//! @}
/*!
\name Adding/Removing Items
*/
@ -844,14 +876,6 @@
//! @{
/*!
\fn void BListView::ScrollToSelection()
\brief Scrolls to selected list item.
\since BeOS R3
*/
/*!
\fn void BListView::Select(int32 index, bool extend)
\brief Selects the list item at the specified \a index.

View File

@ -110,6 +110,7 @@ public:
void* arg), void* arg);
const BListItem** Items() const;
void InvalidateItem(int32 index);
void ScrollTo(int32 index);
void ScrollToSelection();
void Select(int32 index, bool extend = false);

View File

@ -726,21 +726,26 @@ BListView::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
currentMessage->FindInt32("buttons", &buttons);
}
// only update selection if mouse button pressed and not dragging
int32 index = IndexOf(where);
if (buttons == 0 || fTrack->is_dragging)
return BView::MouseMoved(where, code, dragMessage);
// scroll to selection while button is pressed
ScrollToSelection();
// selection updating on drag is for single selection lists only
if (fListType == B_MULTIPLE_SELECTION_LIST || index == -1)
return BView::MouseMoved(where, code, dragMessage);
if (index == -1) {
// If where is above top, scroll to the first item,
// else if where is below bottom scroll to the last item.
if (where.y < Bounds().top)
index = 0;
else if (where.y > Bounds().bottom)
index = CountItems() - 1;
}
// don't scroll if button not pressed, no selection or same item
int32 lastIndex = fFirstSelected;
if (lastIndex != -1 && index != lastIndex) {
// mouse moved over unselected, fake selection until mouse up
if (buttons == 0 || index == -1 || lastIndex == -1 || index == lastIndex)
return BView::MouseMoved(where, code, dragMessage);
// scroll to item under mouse while button is pressed
ScrollTo(index);
if (!fTrack->is_dragging && fListType != B_MULTIPLE_SELECTION_LIST) {
// mouse moved over unselected item, fake selection until mouse up
ItemAt(lastIndex)->Deselect();
ItemAt(index)->Select();
@ -749,7 +754,8 @@ BListView::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage)
// redraw items whose selection has changed
Invalidate(ItemFrame(lastIndex) | ItemFrame(index));
}
} else
Invalidate();
BView::MouseMoved(where, code, dragMessage);
}
@ -1199,6 +1205,23 @@ BListView::InvalidateItem(int32 index)
}
void
BListView::ScrollTo(int32 index)
{
if (index < 0)
index = 0;
if (index > CountItems() - 1)
index = CountItems() - 1;
BRect itemFrame = ItemFrame(index);
BRect bounds = Bounds();
if (itemFrame.top < bounds.top)
ScrollTo(itemFrame.LeftTop());
else if (itemFrame.bottom > bounds.bottom)
ScrollTo(BPoint(0, itemFrame.bottom - bounds.Height()));
}
void
BListView::ScrollToSelection()
{