void ArpOutlineListView::ComputeDimens(ArpDimens& cur_dimens) { float min_w=0, min_h=0; float pref_w=0, pref_h=0; int32 num = CountItems(); int32 max_num = 4; for( int32 i=0; i<num; i++ ) { BListItem* item = ItemAt(i); if( item ) { item->Update(this,BasicFont()); float w = item->Width(); float h = item->Height(); min_h = max(min_h,h); pref_w = max(pref_w,w); if( max_num > 0 ) pref_h += h; max_num--; } } pref_h+=2; float fw = BasicFont()->StringWidth("WWWW"); font_height fhs; BasicFont()->GetHeight(&fhs); float fh = fhs.ascent+fhs.descent+fhs.leading; min_w = max(min_w,fw); min_h = max(min_h,fh); pref_w = max(pref_w,min_w); pref_h = max(pref_h,min_h); cur_dimens.X().SetTo(0, min_w, pref_w, ArpAnySize, 0); cur_dimens.Y().SetTo(0, min_h, pref_h, ArpAnySize, 0); }
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); }
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; }
BList* BOutlineListView::_BuildTree(BListItem* underItem, int32& fullIndex) { int32 fullCount = FullListCountItems(); uint32 level = underItem != NULL ? underItem->OutlineLevel() + 1 : 0; BList* list = new BList; if (underItem != NULL) underItem->fTemporaryList = list; while (fullIndex < fullCount) { BListItem* item = FullListItemAt(fullIndex); // If we jump out of the subtree, break out if (item->fLevel < level) break; // If the level matches, put them into the list // (we handle the case of a missing sublevel gracefully) list->AddItem(item); fullIndex++; if (item->HasSubitems()) { // we're going deeper _BuildTree(item, fullIndex); } } return list; }
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(); } } }
status_t BListView::Archive(BMessage* archive, bool deep) const { status_t status = BView::Archive(archive, deep); if (status < B_OK) return status; status = archive->AddInt32("_lv_type", fListType); if (status == B_OK && deep) { BListItem* item; int32 i = 0; while ((item = ItemAt(i++))) { BMessage subData; status = item->Archive(&subData, true); if (status >= B_OK) status = archive->AddMessage("_l_items", &subData); if (status < B_OK) break; } } if (status >= B_OK && InvocationMessage() != NULL) status = archive->AddMessage("_msg", InvocationMessage()); if (status == B_OK && fSelectMessage != NULL) status = archive->AddMessage("_2nd_msg", fSelectMessage); return status; }
status_t BOutlineListView::Archive(BMessage* archive, bool deep) const { // Note: We can't call the BListView Archive function here, as we are also // interested in subitems BOutlineListView can have. They are even stored // with a different field name (_l_full_items vs. _l_items). status_t status = BView::Archive(archive, deep); if (status != B_OK) return status; status = archive->AddInt32("_lv_type", fListType); if (status == B_OK && deep) { int32 i = 0; BListItem* item = NULL; while ((item = static_cast<BListItem*>(fFullList.ItemAt(i++)))) { BMessage subData; status = item->Archive(&subData, true); if (status >= B_OK) status = archive->AddMessage("_l_full_items", &subData); if (status < B_OK) break; } } if (status >= B_OK && InvocationMessage() != NULL) status = archive->AddMessage("_msg", InvocationMessage()); if (status == B_OK && fSelectMessage != NULL) status = archive->AddMessage("_2nd_msg", fSelectMessage); return status; }
bool ColumnListView::IsExpanded(int32 fullListIndex) const { BListItem* TheItem = (BListItem*)fFullItemList.ItemAt(fullListIndex); if(TheItem) return TheItem->IsExpanded(); else return false; }
int32 MyListView::GetMaxPages (BRect printArea) { // assume pages always fit horizontally int32 maxItems = CountItems(); BListItem *item = FirstItem(); if (item == NULL) return 0; return (int32)ceil(maxItems*item->Height()/printArea.Height()); }
BListItem* NetworkWindow::_CreateItem(const char* label) { BListItem* item = new TitleItem(label); item->SetExpanded(true); fListView->AddItem(item); return item; }
bool BListView::IsItemSelected(int32 index) const { BListItem* item = ItemAt(index); if (item != NULL) return item->IsSelected(); return false; }
bool BOutlineListView::IsExpanded(int32 fullListIndex) { BListItem* item = FullListItemAt(fullListIndex); if (!item) return false; return item->IsExpanded(); }
static void _GetSubItems(BList& sourceList, BList& destList, BListItem* parent, int32 start) { for (int32 i = start; i < sourceList.CountItems(); i++) { BListItem* item = (BListItem*)sourceList.ItemAt(i); if (item->OutlineLevel() <= parent->OutlineLevel()) break; destList.AddItem(item); } }
void MediaWindow::_UpdateListViewMinWidth() { float width = 0; for (int32 i = 0; i < fListView->CountItems(); i++) { BListItem* item = fListView->ItemAt(i); width = max_c(width, item->Width()); } fListView->SetExplicitMinSize(BSize(width, B_SIZE_UNSET)); fListView->InvalidateLayout(); }
void BOutlineListView::_DestructTree(BList* tree) { for (int32 index = tree->CountItems(); index-- > 0;) { BListItem* item = (BListItem*)tree->ItemAt(index); if (item->HasSubitems()) _DestructTree(item->fTemporaryList); } delete tree; }
bool BrowseView::NextInList(BOutlineListView *list, const char *nameToSearch, BListItem *afterThis) { myItem = afterThis; notYet = (afterThis!=NULL); myStr = nameToSearch; list->FullListDoForEach(&iterate,(void*)this); if ((myItem == NULL) || (myItem == afterThis)) { // un item suivant n'a pas été trouvé if (afterThis == NULL) // ben ya vraiment rien return false; // on peut peut être en trouver un avant myItem = NULL; list->FullListDoForEach(&iterate,(void*)this); if ((myItem == NULL) || (myItem == afterThis)) // ça veut vraiment pas! return false; } // on a donc un nouvel item à sélectionner BListItem *iterate = list->Superitem(myItem), *oldIterate = NULL; while (iterate != NULL) { iterate->SetExpanded(true); oldIterate = iterate; iterate = list->Superitem(iterate); } // ce petit truc de Collapse/Expand permet d'être sûr que la outlinelist est mise à jour // j'ai fait comme ça parce que BOutlineListView::Expand() ne marche pas sur un item // qui n'est pas encore visible. BListItem::SetExpanded marche mais ne met pas à jour // l'affichage if (oldIterate != NULL) { list->Collapse(oldIterate); list->Expand(oldIterate); } // maintenant l'item devrait être visible unsigned int n = list->IndexOf(myItem); if (n<0) return false; // ben non! list->Select(n); list->ScrollToSelection(); return true; }
BRect BListView::ItemFrame(int32 index) { BRect frame = Bounds(); if (index < 0 || index >= CountItems()) { frame.top = 0; frame.bottom = -1; } else { BListItem* item = ItemAt(index); frame.top = item->Top(); frame.bottom = item->Bottom(); } return frame; }
void BOutlineListView::_PopulateTree(BList* tree, BList& target, int32& firstIndex, bool onlyVisible) { BListItem** items = (BListItem**)target.Items(); int32 count = tree->CountItems(); for (int32 index = 0; index < count; index++) { BListItem* item = (BListItem*)tree->ItemAtFast(index); items[firstIndex++] = item; if (item->HasSubitems() && (!onlyVisible || item->IsExpanded())) _PopulateTree(item->fTemporaryList, target, firstIndex, onlyVisible); } }
/** * @brief Makes the control enabled or disabled. * @param[in] doEnable true to enable the control, or false to disable the control. */ void BeListViewAdapter::Enable(bool doEnable) { BListView* listView = getListView(); int32 count = listView->CountItems(); int32 index; for (index = 0; index < count; index++) { BListItem* listItem = listView->ItemAt(index); listItem->SetEnabled(doEnable); } listView->LockLooper(); listView->Invalidate(); listView->UnlockLooper(); isEnabled = doEnable; }
void GrepWindow::_OnCheckboxShowLines() { // Selection in BOutlineListView in multiple selection mode // gets weird when collapsing. I've tried all sorts of things. // It seems impossible to make it behave just right. // Going from collapsed to expande mode, the superitems // keep their selection, the subitems don't (yet) have // a selection. This works as expected, AFAIK. // Going from expanded to collapsed mode, I would like // for a selected subitem (line) to select its superitem, // (its file) and the subitem be unselected. // I've successfully tried code patches that apply the // selection pattern that I want, but with weird effects // on subsequent manual selection. // Lines stay selected while the user tries to select // some other line. It just gets weird. // It's as though listItem->Select() and Deselect() // put the items in some semi-selected state. // Or maybe I've got it all wrong. // So, here's the plain basic collapse/expand. // I think it's the least bad of what's possible on BeOS R5, // but perhaps someone comes along with a patch of magic. int32 numItems = fSearchResults->FullListCountItems(); for (int32 x = 0; x < numItems; ++x) { BListItem* listItem = fSearchResults->FullListItemAt(x); if (listItem->OutlineLevel() == 0) { if (fShowLinesCheckbox->Value() == 1) { if (!fSearchResults->IsExpanded(x)) fSearchResults->Expand(listItem); } else { if (fSearchResults->IsExpanded(x)) fSearchResults->Collapse(listItem); } } } fSearchResults->Invalidate(); _SavePrefs(); }
void BOutlineListView::_SortTree(BList* tree, bool oneLevelOnly, int (*compareFunc)(const BListItem* a, const BListItem* b)) { BListItem** items = (BListItem**)tree->Items(); std::sort(items, items + tree->CountItems(), ListItemComparator(compareFunc)); if (oneLevelOnly) return; for (int32 index = tree->CountItems(); index-- > 0;) { BListItem* item = (BListItem*)tree->ItemAt(index); if (item->HasSubitems()) _SortTree(item->fTemporaryList, false, compareFunc); } }
void BListView::Draw(BRect updateRect) { int32 count = CountItems(); if (count == 0) return; BRect itemFrame(0, 0, Bounds().right, -1); for (int i = 0; i < count; i++) { BListItem* item = ItemAt(i); itemFrame.bottom = itemFrame.top + ceilf(item->Height()) - 1; if (itemFrame.Intersects(updateRect)) DrawItem(item, itemFrame); itemFrame.top = itemFrame.bottom + 1; } }
void BListView::_RecalcItemTops(int32 start, int32 end) { int32 count = CountItems(); if ((start < 0) || (start >= count)) return; if (end >= 0) count = end + 1; float top = (start == 0) ? 0.0 : ItemAt(start - 1)->Bottom() + 1.0; for (int32 i = start; i < count; i++) { BListItem *item = ItemAt(i); item->SetTop(top); top += ceilf(item->Height()); } }
bool BOutlineListView::_SwapItems(int32 first, int32 second) { // same item, do nothing if (first == second) return true; // fail, first item out of bounds if ((first < 0) || (first >= CountItems())) return false; // fail, second item out of bounds if ((second < 0) || (second >= CountItems())) return false; int32 firstIndex = min_c(first, second); int32 secondIndex = max_c(first, second); BListItem* firstItem = ItemAt(firstIndex); BListItem* secondItem = ItemAt(secondIndex); BList firstSubItems, secondSubItems; if (Superitem(firstItem) != Superitem(secondItem)) return false; if (!firstItem->IsItemVisible() || !secondItem->IsItemVisible()) return false; int32 fullFirstIndex = _FullListIndex(firstIndex); int32 fullSecondIndex = _FullListIndex(secondIndex); _GetSubItems(fFullList, firstSubItems, firstItem, fullFirstIndex + 1); _GetSubItems(fFullList, secondSubItems, secondItem, fullSecondIndex + 1); _DoSwap(fFullList, fullFirstIndex, fullSecondIndex, &firstSubItems, &secondSubItems); _CullInvisibleItems(firstSubItems); _CullInvisibleItems(secondSubItems); _DoSwap(fList, firstIndex, secondIndex, &firstSubItems, &secondSubItems); _RecalcItemTops(firstIndex); _RescanSelection(firstIndex, secondIndex + secondSubItems.CountItems()); Invalidate(Bounds()); return true; }
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; }
void GrepWindow::_OnInvokeItem() { for (int32 selectionIndex = 0; ; selectionIndex++) { int32 itemIndex = fSearchResults->CurrentSelection(selectionIndex); BListItem* item = fSearchResults->ItemAt(itemIndex); if (item == NULL) break; int32 level = item->OutlineLevel(); int32 lineNum = -1; // Get the line number. // only this level has line numbers if (level == 1) { BStringItem* str = dynamic_cast<BStringItem*>(item); if (str != NULL) { lineNum = atol(str->Text()); // fortunately, atol knows when to stop the conversion } } // Get the top-most item and launch its entry_ref. while (level != 0) { item = fSearchResults->Superitem(item); if (item == NULL) break; level = item->OutlineLevel(); } ResultItem* entry = dynamic_cast<ResultItem*>(item); if (entry != NULL) { bool done = false; if (fModel->fInvokePe) done = _OpenInPe(entry->ref, lineNum); if (!done) be_roster->Launch(&entry->ref); } } }
/*! 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; }
void BOutlineListView::MouseDown(BPoint point) { MakeFocus(); int32 index = IndexOf(point); if (index != -1) { BListItem* item = ItemAt(index); if (item->fHasSubitems && LatchRect(ItemFrame(index), item->fLevel).Contains(point)) { if (item->IsExpanded()) Collapse(item); else Expand(item); } else BListView::MouseDown(point); } }
bool BOutlineListView::AddItem(BListItem* item, int32 fullListIndex) { if (fullListIndex < 0) fullListIndex = 0; else if (fullListIndex > FullListCountItems()) fullListIndex = FullListCountItems(); if (!fFullList.AddItem(item, fullListIndex)) return false; // Check if this item is visible, and if it is, add it to the // other list, too if (item->fLevel > 0) { BListItem* super = _SuperitemForIndex(fullListIndex, item->fLevel); if (super == NULL) return true; bool hadSubitems = super->fHasSubitems; super->fHasSubitems = true; if (!super->IsItemVisible() || !super->IsExpanded()) { item->SetItemVisible(false); return true; } if (!hadSubitems) Invalidate(LatchRect(ItemFrame(IndexOf(super)), super->OutlineLevel())); } int32 listIndex = _FindPreviousVisibleIndex(fullListIndex); if (!BListView::AddItem(item, IndexOf(FullListItemAt(listIndex)) + 1)) { // adding didn't work out, we need to remove it from the main list again fFullList.RemoveItem(fullListIndex); return false; } 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()); }