diff --git a/headers/os/interface/ListView.h b/headers/os/interface/ListView.h index ef5b6b5be4..56878a945e 100644 --- a/headers/os/interface/ListView.h +++ b/headers/os/interface/ListView.h @@ -189,6 +189,9 @@ private: bool _ReplaceItem(int32 index, BListItem* item); void _RescanSelection(int32 from, int32 to); + void _DoneTracking(BPoint where); + void _Track(BPoint where, uint32); + private: BList fList; list_view_type fListType; diff --git a/src/kits/interface/ListView.cpp b/src/kits/interface/ListView.cpp index bc8f091f1c..f26e2e7484 100644 --- a/src/kits/interface/ListView.cpp +++ b/src/kits/interface/ListView.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -568,7 +569,7 @@ BListView::MouseDown(BPoint where) if (doubleClick && index >= fFirstSelected && index <= fLastSelected) { fTrack->drag_start.Set(INT32_MAX, INT32_MAX); Invoke(); - return; + return BView::MouseDown(where); } if (!doubleClick) { @@ -577,6 +578,9 @@ BListView::MouseDown(BPoint where) fTrack->item_index = index; fTrack->was_selected = index >= 0 ? ItemAt(index)->IsSelected() : false; fTrack->try_drag = true; + + MouseDownThread::TrackMouse(this, + &BListView::_DoneTracking, &BListView::_Track); } if (index >= 0) { @@ -613,33 +617,22 @@ BListView::MouseDown(BPoint where) } } else if ((modifiers & B_COMMAND_KEY) == 0) DeselectAll(); + + BView::MouseDown(where); } void BListView::MouseUp(BPoint where) { - fTrack->try_drag = false; + BView::MouseUp(where); } void BListView::MouseMoved(BPoint where, uint32 code, const BMessage* dragMessage) { - if (fTrack->item_index == -1 || !fTrack->try_drag) { - // mouse was not clicked above any item - // or no mouse button pressed - return; - } - - // Initiate a drag if the mouse was moved far enough - BPoint offset = where - fTrack->drag_start; - float dragDistance = sqrtf(offset.x * offset.x + offset.y * offset.y); - if (dragDistance >= 5.0f) { - fTrack->try_drag = false; - InitiateDrag(fTrack->drag_start, fTrack->item_index, - fTrack->was_selected); - } + BView::MouseMoved(where, code, dragMessage); } @@ -1945,3 +1938,41 @@ BListView::_RecalcItemTops(int32 start, int32 end) top += ceilf(item->Height()); } } + + +void +BListView::_DoneTracking(BPoint where) +{ + fTrack->try_drag = false; +} + + +void +BListView::_Track(BPoint where, uint32) +{ + int32 index = IndexOf(where); + BListItem* item = ItemAt(index); + + if (item != NULL && !item->IsSelected() && item->IsEnabled()) { + Select(index, fListType == B_MULTIPLE_SELECTION_LIST + && (modifiers() & B_SHIFT_KEY) != 0); + ScrollToSelection(); + fTrack->try_drag = false; + // don't try to initiate a drag once selection changes + } + + if (fTrack->item_index < 0 || !fTrack->try_drag) { + // mouse was not clicked above any item + // or no mouse button pressed + return; + } + + // Initiate a drag if the mouse was moved far enough + BPoint offset = where - fTrack->drag_start; + float dragDistance = sqrtf(offset.x * offset.x + offset.y * offset.y); + if (dragDistance >= 5.0f) { + fTrack->try_drag = false; + InitiateDrag(fTrack->drag_start, fTrack->item_index, + fTrack->was_selected); + } +}