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); }
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()); }
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()); } }
// InitiateDrag bool DragSortableListView::InitiateDrag( BPoint point, int32 index, bool ) { // supress drag&drop while an item is focused if (fFocusedIndex >= 0) return false; bool success = false; BListItem* item = ItemAt( CurrentSelection( 0 ) ); if ( !item ) { // workarround a timing problem Select( index ); item = ItemAt( index ); } if ( item ) { // create drag message BMessage msg( fDragCommand ); MakeDragMessage( &msg ); // figure out drag rect float width = Bounds().Width(); BRect dragRect(0.0, 0.0, width, -1.0); // figure out, how many items fit into our bitmap int32 numItems; bool fade = false; for (numItems = 0; BListItem* item = ItemAt( CurrentSelection( numItems ) ); numItems++) { dragRect.bottom += ceilf( item->Height() ) + 1.0; if ( dragRect.Height() > MAX_DRAG_HEIGHT ) { fade = true; dragRect.bottom = MAX_DRAG_HEIGHT; numItems++; break; } } BBitmap* dragBitmap = new BBitmap( dragRect, B_RGB32, true ); if ( dragBitmap && dragBitmap->IsValid() ) { if ( BView *v = new BView( dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW ) ) { dragBitmap->AddChild( v ); dragBitmap->Lock(); BRect itemBounds( dragRect) ; itemBounds.bottom = 0.0; // let all selected items, that fit into our drag_bitmap, draw for ( int32 i = 0; i < numItems; i++ ) { int32 index = CurrentSelection( i ); BListItem* item = ItemAt( index ); itemBounds.bottom = itemBounds.top + ceilf( item->Height() ); if ( itemBounds.bottom > dragRect.bottom ) itemBounds.bottom = dragRect.bottom; DrawListItem( v, index, itemBounds ); itemBounds.top = itemBounds.bottom + 1.0; } // make a black frame arround the edge v->SetHighColor( 0, 0, 0, 255 ); v->StrokeRect( v->Bounds() ); v->Sync(); uint8 *bits = (uint8 *)dragBitmap->Bits(); int32 height = (int32)dragBitmap->Bounds().Height() + 1; int32 width = (int32)dragBitmap->Bounds().Width() + 1; int32 bpr = dragBitmap->BytesPerRow(); if (fade) { for ( int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr ) { uint8 *line = bits + 3; for (uint8 *end = line + 4 * width; line < end; line += 4) *line = ALPHA; } for ( int32 y = height - ALPHA / 2; y < height; y++, bits += bpr ) { uint8 *line = bits + 3; for (uint8 *end = line + 4 * width; line < end; line += 4) *line = (height - y) << 1; } } else { for ( int32 y = 0; y < height; y++, bits += bpr ) { uint8 *line = bits + 3; for (uint8 *end = line + 4 * width; line < end; line += 4) *line = ALPHA; } } dragBitmap->Unlock(); } } else { delete dragBitmap; dragBitmap = NULL; } if (dragBitmap) DragMessage( &msg, dragBitmap, B_OP_ALPHA, BPoint( 0.0, 0.0 ) ); else DragMessage( &msg, dragRect.OffsetToCopy( point ), this ); _SetDragMessage(&msg); success = true; } return success; }
bool AudioListView::InitiateDrag(BPoint point, int32 dragIndex, bool) { BListItem* item = ItemAt(CurrentSelection(0)); if (item == NULL) { // workaround for a timing problem (see Locale prefs) Select(dragIndex); item = ItemAt(dragIndex); } if (item == NULL) return false; // create drag message BMessage message(kDraggedItem); for (int32 i = 0;; i++) { int32 index = CurrentSelection(i); if (index < 0) break; message.AddPointer("trackitem", ItemAt(CurrentSelection(i))); } // figure out drag rect BRect dragRect(0.0, 0.0, Bounds().Width(), -1.0); // figure out, how many items fit into our bitmap bool fade = false; for (int32 i = 0; message.FindPointer("trackitem", i, reinterpret_cast<void**>(&item)) == B_OK; i++) { dragRect.bottom += ceilf(item->Height()) + 1.0; if (dragRect.Height() > MAX_DRAG_HEIGHT) { dragRect.bottom = MAX_DRAG_HEIGHT; fade = true; break; } } BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true); if (dragBitmap->IsValid()) { BView* view = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW); dragBitmap->AddChild(view); dragBitmap->Lock(); BRect itemBounds(dragRect) ; itemBounds.bottom = 0.0; // let all selected items, that fit into our drag_bitmap, draw for (int32 i = 0; message.FindPointer("trackitem", i, reinterpret_cast<void**>(&item)) == B_OK; i++) { AudioListItem* item; message.FindPointer("trackitem", i, reinterpret_cast<void**>(&item)); itemBounds.bottom = itemBounds.top + ceilf(item->Height()); if (itemBounds.bottom > dragRect.bottom) itemBounds.bottom = dragRect.bottom; item->DrawItem(view, itemBounds); itemBounds.top = itemBounds.bottom + 1.0; } // make a black frame around the edge view->SetHighColor(0, 0, 0, 255); view->StrokeRect(view->Bounds()); view->Sync(); uint8* bits = (uint8*)dragBitmap->Bits(); int32 height = (int32)dragBitmap->Bounds().Height() + 1; int32 width = (int32)dragBitmap->Bounds().Width() + 1; int32 bpr = dragBitmap->BytesPerRow(); if (fade) { for (int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = ALPHA; } for (int32 y = height - ALPHA / 2; y < height; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = (height - y) << 1; } } else { for (int32 y = 0; y < height; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = ALPHA; } } dragBitmap->Unlock(); } else { delete dragBitmap; dragBitmap = NULL; } if (dragBitmap != NULL) DragMessage(&message, dragBitmap, B_OP_ALPHA, BPoint(0.0, 0.0)); else DragMessage(&message, dragRect.OffsetToCopy(point), this); return true; }
bool LanguageListView::InitiateDrag(BPoint point, int32 dragIndex, bool /*wasSelected*/) { if (fDragMessage == NULL) return false; BListItem* item = ItemAt(CurrentSelection(0)); if (item == NULL) { // workaround for a timing problem // TODO: this should support extending the selection item = ItemAt(dragIndex); Select(dragIndex); } if (item == NULL) return false; // create drag message BMessage message = *fDragMessage; message.AddPointer("listview", this); for (int32 i = 0;; i++) { int32 index = CurrentSelection(i); if (index < 0) break; message.AddInt32("index", index); } // figure out drag rect BRect dragRect(0.0, 0.0, Bounds().Width(), -1.0); int32 numItems = 0; bool fade = false; // figure out, how many items fit into our bitmap for (int32 i = 0, index; message.FindInt32("index", i, &index) == B_OK; i++) { BListItem* item = ItemAt(index); if (item == NULL) break; dragRect.bottom += ceilf(item->Height()) + 1.0; numItems++; if (dragRect.Height() > MAX_DRAG_HEIGHT) { dragRect.bottom = MAX_DRAG_HEIGHT; fade = true; break; } } BBitmap* dragBitmap = new BBitmap(dragRect, B_RGB32, true); if (dragBitmap->IsValid()) { BView* view = new BView(dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW); dragBitmap->AddChild(view); dragBitmap->Lock(); BRect itemBounds(dragRect) ; itemBounds.bottom = 0.0; // let all selected items, that fit into our drag_bitmap, draw for (int32 i = 0; i < numItems; i++) { int32 index = message.FindInt32("index", i); LanguageListItem* item = static_cast<LanguageListItem*>(ItemAt(index)); itemBounds.bottom = itemBounds.top + ceilf(item->Height()); if (itemBounds.bottom > dragRect.bottom) itemBounds.bottom = dragRect.bottom; item->DrawItem(view, itemBounds); itemBounds.top = itemBounds.bottom + 1.0; } // make a black frame arround the edge view->SetHighColor(0, 0, 0, 255); view->StrokeRect(view->Bounds()); view->Sync(); uint8* bits = (uint8*)dragBitmap->Bits(); int32 height = (int32)dragBitmap->Bounds().Height() + 1; int32 width = (int32)dragBitmap->Bounds().Width() + 1; int32 bpr = dragBitmap->BytesPerRow(); if (fade) { for (int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = ALPHA; } for (int32 y = height - ALPHA / 2; y < height; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = (height - y) << 1; } } else { for (int32 y = 0; y < height; y++, bits += bpr) { uint8* line = bits + 3; for (uint8* end = line + 4 * width; line < end; line += 4) *line = ALPHA; } } dragBitmap->Unlock(); } else { delete dragBitmap; dragBitmap = NULL; } if (dragBitmap != NULL) DragMessage(&message, dragBitmap, B_OP_ALPHA, BPoint(0.0, 0.0)); else DragMessage(&message, dragRect.OffsetToCopy(point), this); return true; }