diff --git a/docs/user/interface/ListView.dox b/docs/user/interface/ListView.dox index aadb688efd..582b7eb581 100644 --- a/docs/user/interface/ListView.dox +++ b/docs/user/interface/ListView.dox @@ -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. diff --git a/headers/os/interface/ListView.h b/headers/os/interface/ListView.h index 7843489edd..3b907dccd0 100644 --- a/headers/os/interface/ListView.h +++ b/headers/os/interface/ListView.h @@ -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); diff --git a/src/kits/interface/ListView.cpp b/src/kits/interface/ListView.cpp index aa329a1e90..5efe2139d8 100644 --- a/src/kits/interface/ListView.cpp +++ b/src/kits/interface/ListView.cpp @@ -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() {