BListItem* BListView::RemoveItem(int32 index) { BListItem* item = ItemAt(index); if (item == NULL) return NULL; if (item->IsSelected()) Deselect(index); if (!fList.RemoveItem(item)) return NULL; if (fFirstSelected != -1 && index < fFirstSelected) fFirstSelected--; if (fLastSelected != -1 && index < fLastSelected) fLastSelected--; if (fAnchorIndex != -1 && index < fAnchorIndex) fAnchorIndex--; _RecalcItemTops(index); _InvalidateFrom(index); _FixupScrollBar(); return item; }
void BListView::_Track(BPoint where, uint32) { if (fTrack->item_index >= 0 && fTrack->try_drag) { // 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; fTrack->is_dragging = InitiateDrag(fTrack->drag_start, fTrack->item_index, fTrack->was_selected); } } if (!fTrack->is_dragging) { // do selection only if a drag was not initiated 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(); } } }
void AudioListView::MouseDown(BPoint position) { if (!IsEmpty()) { bool onSelection = false; BListItem* item = ItemAt(IndexOf(position)); if (item != NULL && item->IsSelected()) onSelection = true; uint32 buttons = 0; if (Window() != NULL && Window()->CurrentMessage() != NULL) buttons = Window()->CurrentMessage()->FindInt32("buttons"); if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0) { if (CurrentSelection() < 0 || !onSelection) Select(IndexOf(position)); if (CurrentSelection() >= 0) _ShowPopUpMenu(ConvertToScreen(position)); return; } } BListView::MouseDown(position); }
bool BListView::IsItemSelected(int32 index) const { BListItem* item = ItemAt(index); if (item != NULL) return item->IsSelected(); return false; }
bool BListView::_ReplaceItem(int32 index, BListItem* item) { if (item == NULL) return false; BListItem* old = ItemAt(index); if (!old) return false; BRect frame = ItemFrame(index); bool selectionChanged = old->IsSelected() != item->IsSelected(); // replace item if (!fList.ReplaceItem(index, item)) return false; // tack selection if (selectionChanged) { int32 start = min_c(fFirstSelected, index); int32 end = max_c(fLastSelected, index); _RescanSelection(start, end); SelectionChanged(); } _RecalcItemTops(index); bool itemHeightChanged = frame != ItemFrame(index); // take care of invalidation if (Window()) { // NOTE: window looper is assumed to be locked! if (itemHeightChanged) _InvalidateFrom(index); else Invalidate(frame); } if (itemHeightChanged) _FixupScrollBar(); return true; }
/*! Selects the item at the specified \a index, and returns \c true in case the selection was changed because of this method. If \a extend is \c false, all previously selected items are deselected. */ bool BListView::_Select(int32 index, bool extend) { if (index < 0 || index >= CountItems()) return false; // only lock the window when there is one BAutolock locker(Window()); if (Window() != NULL && !locker.IsLocked()) return false; bool changed = false; if (!extend && fFirstSelected != -1) changed = _DeselectAll(index, index); fAnchorIndex = index; BListItem* item = ItemAt(index); if (!item->IsEnabled() || item->IsSelected()) { // if the item is already selected, or can't be selected, // we're done here return changed; } // keep track of first and last selected item if (fFirstSelected == -1) { // no previous selection fFirstSelected = index; fLastSelected = index; } else if (index < fFirstSelected) { fFirstSelected = index; } else if (index > fLastSelected) { fLastSelected = index; } ItemAt(index)->Select(); if (Window()) InvalidateItem(index); return true; }
// ObjectChanged void DragSortableListView::ObjectChanged(const Observable* object) { if (object != fSelection || fModifyingSelection || fSyncingToSelection) return; //printf("%s - syncing start\n", Name()); fSyncingToSelection = true; // try to sync to Selection BList selectedItems; int32 count = fSelection->CountSelected(); for (int32 i = 0; i < count; i++) { int32 index = IndexOfSelectable(fSelection->SelectableAtFast(i)); if (index >= 0) { BListItem* item = ItemAt(index); if (item && !selectedItems.HasItem((void*)item)) selectedItems.AddItem((void*)item); } } count = selectedItems.CountItems(); if (count == 0) { if (CurrentSelection(0) >= 0) DeselectAll(); } else { count = CountItems(); for (int32 i = 0; i < count; i++) { BListItem* item = ItemAt(i); bool selected = selectedItems.RemoveItem((void*)item); if (item->IsSelected() != selected) { Select(i, true); } } } fSyncingToSelection = false; //printf("%s - done\n", Name()); }
/*! Selects the items between \a from and \a to, and returns \c true in case the selection was changed because of this method. If \a extend is \c false, all previously selected items are deselected. */ bool BListView::_Select(int32 from, int32 to, bool extend) { if (to < from) return false; BAutolock locker(Window()); if (Window() && !locker.IsLocked()) return false; bool changed = false; if (fFirstSelected != -1 && !extend) changed = _DeselectAll(from, to); if (fFirstSelected == -1) { fFirstSelected = from; fLastSelected = to; } else { if (from < fFirstSelected) fFirstSelected = from; if (to > fLastSelected) fLastSelected = to; } for (int32 i = from; i <= to; ++i) { BListItem *item = ItemAt(i); if (item && !item->IsSelected()) { item->Select(); if (Window()) InvalidateItem(i); changed = true; } } return changed; }
// MouseDown void DragSortableListView::MouseDown( BPoint where ) { int32 clicks = 1; uint32 buttons = 0; Window()->CurrentMessage()->FindInt32("clicks", &clicks); Window()->CurrentMessage()->FindInt32("buttons", (int32*)&buttons); int32 clickedIndex = -1; for (int32 i = 0; BListItem* item = ItemAt(i); i++) { if (ItemFrame(i).Contains(where)) { if (clicks == 2) { // only do something if user clicked the same item twice if (fLastClickedItem == item) DoubleClicked(i); } else { // remember last clicked item fLastClickedItem = item; } clickedIndex = i; break; } } if (clickedIndex == -1) fLastClickedItem = NULL; BListItem* item = ItemAt(clickedIndex); if (ListType() == B_MULTIPLE_SELECTION_LIST && item && (buttons & B_SECONDARY_MOUSE_BUTTON)) { if (item->IsSelected()) Deselect(clickedIndex); else Select(clickedIndex, true); } else { BListView::MouseDown(where); } }
bool BListView::_DeselectAll(int32 exceptFrom, int32 exceptTo) { if (fFirstSelected == -1) return false; BAutolock locker(Window()); if (Window() && !locker.IsLocked()) return false; bool changed = false; for (int32 index = fFirstSelected; index <= fLastSelected; index++) { // don't deselect the items we shouldn't deselect if (exceptFrom != -1 && exceptFrom <= index && exceptTo >= index) continue; BListItem *item = ItemAt(index); if (item && item->IsSelected()) { item->Deselect(); InvalidateItem(index); changed = true; } } if (!changed) return false; if (exceptFrom != -1) { fFirstSelected = _CalcFirstSelected(exceptFrom); fLastSelected = _CalcLastSelected(exceptTo); } else fFirstSelected = fLastSelected = -1; return true; }
bool BListView::_Deselect(int32 index) { if (index < 0 || index >= CountItems()) return false; BWindow *window = Window(); BAutolock locker(window); if (window && !locker.IsLocked()) return false; BListItem *item = ItemAt(index); if (item && item->IsSelected()) { BRect frame(ItemFrame(index)); BRect bounds(Bounds()); item->Deselect(); if (fFirstSelected == index && fLastSelected == index) { fFirstSelected = -1; fLastSelected = -1; } else { if (fFirstSelected == index) fFirstSelected = _CalcFirstSelected(index); if (fLastSelected == index) fLastSelected = _CalcLastSelected(index); } if (window && bounds.Intersects(frame)) DrawItem(ItemAt(index), frame, true); } return true; }
void NamesView::MouseDown (BPoint myPoint) { int32 selected (IndexOf (myPoint)); bool handled (false); if (selected < 0) { DeselectAll(); return; } BMessage *inputMsg (Window()->CurrentMessage()); int32 mousebuttons (0), keymodifiers (0), mouseclicks (0); inputMsg->FindInt32 ("buttons", &mousebuttons); inputMsg->FindInt32 ("modifiers", &keymodifiers); inputMsg->FindInt32 ("clicks", &mouseclicks); if (mouseclicks > 1 && CurrentSelection(1) <= 0 && mousebuttons == B_PRIMARY_MOUSE_BUTTON && (keymodifiers & B_SHIFT_KEY) == 0 && (keymodifiers & B_OPTION_KEY) == 0 && (keymodifiers & B_COMMAND_KEY) == 0 && (keymodifiers & B_CONTROL_KEY) == 0) { // user double clicked BListItem *item (ItemAt (IndexOf(myPoint))); if (item && !item->IsSelected()) { // "double" clicked away from another selection Select (IndexOf (myPoint), false); fCurrentindex = IndexOf (myPoint); fTracking = true; } else if (item && item->IsSelected()) { // double clicking on a single item NameItem *myItem (reinterpret_cast<NameItem *>(item)); BString theNick (myItem->Name()); BMessage msg (M_OPEN_MSGAGENT); msg.AddString ("nick", theNick.String()); reinterpret_cast<ChannelAgent *>(Parent()->Parent())->fMsgr.SendMessage (&msg); } handled = true; } if (mouseclicks == 1 && CurrentSelection(1) <= 0 && mousebuttons == B_PRIMARY_MOUSE_BUTTON && (keymodifiers & B_SHIFT_KEY) == 0 && (keymodifiers & B_OPTION_KEY) == 0 && (keymodifiers & B_COMMAND_KEY) == 0 && (keymodifiers & B_CONTROL_KEY) == 0) { // user single clicks BListItem *item (ItemAt (IndexOf(myPoint))); if (item && !item->IsSelected()) Select (IndexOf (myPoint), false); fTracking = true; fCurrentindex = IndexOf (myPoint); handled = true; } if (mouseclicks >= 1 && CurrentSelection(1) >= 0 && mousebuttons == B_PRIMARY_MOUSE_BUTTON && (keymodifiers & B_SHIFT_KEY) == 0 && (keymodifiers & B_OPTION_KEY) == 0 && (keymodifiers & B_COMMAND_KEY) == 0 && (keymodifiers & B_CONTROL_KEY) == 0) { // user clicks on something in the middle of a sweep selection BListItem *item (ItemAt (IndexOf(myPoint))); if (item) Select (IndexOf (myPoint), false); fTracking = true; fCurrentindex = IndexOf (myPoint); handled = true; } if (mousebuttons == B_SECONDARY_MOUSE_BUTTON && (keymodifiers & B_SHIFT_KEY) == 0 && (keymodifiers & B_OPTION_KEY) == 0 && (keymodifiers & B_COMMAND_KEY) == 0 && (keymodifiers & B_CONTROL_KEY) == 0) { // user right clicks - display popup menu BListItem *item (ItemAt (IndexOf(myPoint))); if (item && !item->IsSelected()) Select (IndexOf (myPoint), false); fMyPopUp->Go ( ConvertToScreen (myPoint), true, false, ConvertToScreen (ItemFrame (selected))); handled = true; } if (mousebuttons == B_TERTIARY_MOUSE_BUTTON) BListView::MouseDown (myPoint); fLastSelected = selected; if (!handled) BListView::MouseDown (myPoint); }