1 /*****************************************************************************
2 * ListViews.h: BeOS interface list view class implementation
3 *****************************************************************************
4 * Copyright (C) 1999, 2000, 2001 the VideoLAN team
7 * Authors: Stephan Aßmus <stippi@yellowbites.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
37 #include <vlc_common.h>
38 #include <vlc_interface.h>
40 #include "InterfaceWindow.h"
41 #include "ListViews.h"
44 #define MAX_DRAG_HEIGHT 200.0
46 #define TEXT_OFFSET 20.0
48 /*****************************************************************************
50 *****************************************************************************/
51 PlaylistItem::PlaylistItem( const char *name )
52 : BStringItem( name ),
56 if ( get_ref_for_path( name, &ref) == B_OK )
57 fName.SetTo( ref.name );
60 PlaylistItem::~PlaylistItem()
64 /*****************************************************************************
65 * PlaylistItem::DrawItem
66 *****************************************************************************/
68 PlaylistItem::Draw( BView *owner, BRect frame, bool tintedLine,
69 uint32 mode, bool active, bool playing )
71 rgb_color color = (rgb_color){ 255, 255, 255, 255 };
73 color = tint_color( color, 1.04 );
76 color = tint_color( color, B_DARKEN_2_TINT );
77 owner->SetLowColor( color );
78 owner->FillRect( frame, B_SOLID_LOW );
80 owner->SetHighColor( 0, 0, 0, 255 );
82 owner->GetFontHeight( &fh );
83 const char* text = Text();
87 if ( fName.CountChars() > 0 )
88 text = fName.String();
94 BString truncatedString( text );
95 owner->TruncateString( &truncatedString, B_TRUNCATE_MIDDLE,
96 frame.Width() - TEXT_OFFSET - 4.0 );
97 owner->DrawString( truncatedString.String(),
98 BPoint( frame.left + TEXT_OFFSET,
99 frame.top + fh.ascent + 1.0 ) );
103 rgb_color black = (rgb_color){ 0, 0, 0, 255 };
104 rgb_color green = (rgb_color){ 0, 255, 0, 255 };
105 BRect r( 0.0, 0.0, 10.0, 10.0 );
106 r.OffsetTo( frame.left + 4.0,
107 ceilf( ( frame.top + frame.bottom ) / 2.0 ) - 5.0 );
109 green = tint_color( color, B_DARKEN_1_TINT );
110 rgb_color lightGreen = tint_color( green, B_LIGHTEN_2_TINT );
111 rgb_color darkGreen = tint_color( green, B_DARKEN_2_TINT );
113 arrow[0] = r.LeftTop();
114 arrow[1] = r.LeftBottom();
115 arrow[2].x = r.right;
116 arrow[2].y = ( r.top + r.bottom ) / 2.0;
117 owner->BeginLineArray( 6 );
119 owner->AddLine( arrow[0], arrow[1], black );
120 owner->AddLine( BPoint( arrow[1].x + 1.0, arrow[1].y - 1.0 ),
122 owner->AddLine( arrow[0], arrow[2], black );
129 // highlights and shadow
130 owner->AddLine( arrow[1], arrow[2], darkGreen );
131 owner->AddLine( arrow[0], arrow[2], lightGreen );
132 owner->AddLine( arrow[0], arrow[1], lightGreen );
133 owner->EndLineArray();
140 owner->SetHighColor( green );
141 owner->FillPolygon( arrow, 3 );
145 /*****************************************************************************
146 * DragSortableListView class
147 *****************************************************************************/
148 DragSortableListView::DragSortableListView( BRect frame, const char* name,
149 list_view_type type, uint32 resizingMode,
151 : BListView( frame, name, type, resizingMode, flags ),
152 fDropRect( 0.0, 0.0, -1.0, -1.0 ),
155 SetViewColor( B_TRANSPARENT_32_BIT );
158 DragSortableListView::~DragSortableListView()
162 /*****************************************************************************
163 * DragSortableListView::Draw
164 *****************************************************************************/
166 DragSortableListView::Draw( BRect updateRect )
168 int32 firstIndex = IndexOf( updateRect.LeftTop() );
169 int32 lastIndex = IndexOf( updateRect.RightBottom() );
170 if ( firstIndex >= 0 )
172 if ( lastIndex < firstIndex )
173 lastIndex = CountItems() - 1;
174 // update rect contains items
175 BRect r( updateRect );
176 for ( int32 i = firstIndex; i <= lastIndex; i++)
179 DrawListItem( this, i, r );
181 updateRect.top = r.bottom + 1.0;
182 if ( updateRect.IsValid() )
184 SetLowColor( 255, 255, 255, 255 );
185 FillRect( updateRect, B_SOLID_LOW );
190 SetLowColor( 255, 255, 255, 255 );
191 FillRect( updateRect, B_SOLID_LOW );
193 // drop anticipation indication
194 if ( fDropRect.IsValid() )
196 SetHighColor( 255, 0, 0, 255 );
197 StrokeRect( fDropRect );
201 /*****************************************************************************
202 * DragSortableListView::InitiateDrag
203 *****************************************************************************/
205 DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
207 bool success = false;
208 BListItem* item = ItemAt( CurrentSelection( 0 ) );
211 // workarround a timing problem
213 item = ItemAt( index );
217 // create drag message
218 BMessage msg( B_SIMPLE_DATA );
219 MakeDragMessage( &msg );
220 // figure out drag rect
221 float width = Bounds().Width();
222 BRect dragRect(0.0, 0.0, width, -1.0);
223 // figure out, how many items fit into our bitmap
226 for (numItems = 0; BListItem* item = ItemAt( CurrentSelection( numItems ) ); numItems++) {
227 dragRect.bottom += ceilf( item->Height() ) + 1.0;
228 if ( dragRect.Height() > MAX_DRAG_HEIGHT ) {
230 dragRect.bottom = MAX_DRAG_HEIGHT;
235 BBitmap* dragBitmap = new BBitmap( dragRect, B_RGB32, true );
236 if ( dragBitmap && dragBitmap->IsValid() ) {
237 if ( BView *v = new BView( dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW ) ) {
238 dragBitmap->AddChild( v );
240 BRect itemBounds( dragRect) ;
241 itemBounds.bottom = 0.0;
242 // let all selected items, that fit into our drag_bitmap, draw
243 for ( int32 i = 0; i < numItems; i++ ) {
244 int32 index = CurrentSelection( i );
245 BListItem* item = ItemAt( index );
246 itemBounds.bottom = itemBounds.top + ceilf( item->Height() );
247 if ( itemBounds.bottom > dragRect.bottom )
248 itemBounds.bottom = dragRect.bottom;
249 DrawListItem( v, index, itemBounds );
250 itemBounds.top = itemBounds.bottom + 1.0;
252 // make a black frame arround the edge
253 v->SetHighColor( 0, 0, 0, 255 );
254 v->StrokeRect( v->Bounds() );
257 uint8 *bits = (uint8 *)dragBitmap->Bits();
258 int32 height = (int32)dragBitmap->Bounds().Height() + 1;
259 int32 width = (int32)dragBitmap->Bounds().Width() + 1;
260 int32 bpr = dragBitmap->BytesPerRow();
263 for ( int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr ) {
264 uint8 *line = bits + 3;
265 for (uint8 *end = line + 4 * width; line < end; line += 4)
268 for ( int32 y = height - ALPHA / 2; y < height; y++, bits += bpr ) {
269 uint8 *line = bits + 3;
270 for (uint8 *end = line + 4 * width; line < end; line += 4)
271 *line = (height - y) << 1;
274 for ( int32 y = 0; y < height; y++, bits += bpr ) {
275 uint8 *line = bits + 3;
276 for (uint8 *end = line + 4 * width; line < end; line += 4)
280 dragBitmap->Unlock();
285 DragMessage( &msg, dragBitmap, B_OP_ALPHA, BPoint( 0.0, 0.0 ) );
288 DragMessage( &msg, dragRect.OffsetToCopy( point ), this );
294 /*****************************************************************************
295 * DragSortableListView::WindowActivated
296 *****************************************************************************/
298 DragSortableListView::WindowActivated( bool active )
300 // workarround for buggy focus indication of BScrollView
301 if ( BView* view = Parent() )
305 /*****************************************************************************
306 * DragSortableListView::MessageReceived
307 *****************************************************************************/
309 DragSortableListView::MessageReceived(BMessage* message)
311 switch ( message->what )
313 case B_MODIFIERS_CHANGED:
318 DragSortableListView *list = NULL;
319 if ( message->FindPointer( "list", (void **)&list ) == B_OK
322 int32 count = CountItems();
323 if ( fDropIndex < 0 || fDropIndex > count )
327 for ( int32 i = 0; message->FindInt32( "index", i, &index ) == B_OK; i++ )
328 if ( BListItem* item = ItemAt(index) )
329 items.AddItem( (void*)item );
330 if ( items.CountItems() > 0 )
332 if ( modifiers() & B_SHIFT_KEY )
333 CopyItems( items, fDropIndex );
335 MoveItems( items, fDropIndex );
342 BListView::MessageReceived( message );
347 /*****************************************************************************
348 * DragSortableListView::MouseMoved
349 *****************************************************************************/
351 DragSortableListView::MouseMoved(BPoint where, uint32 transit, const BMessage *msg)
353 if ( msg && ( msg->what == B_SIMPLE_DATA || msg->what == MSG_SOUNDPLAY ) )
355 bool replaceAll = !msg->HasPointer("list") && !(modifiers() & B_SHIFT_KEY);
359 // remember drag message
360 // this is needed to react on modifier changes
361 fDragMessageCopy = *msg;
367 r.bottom--; // compensate for scrollbar offset
368 _SetDropAnticipationRect( r );
373 // offset where by half of item height
374 BRect r( ItemFrame( 0 ) );
375 where.y += r.Height() / 2.0;
377 int32 index = IndexOf( where );
379 index = CountItems();
380 _SetDropIndex( index );
385 // forget drag message
386 fDragMessageCopy.what = 0;
388 _RemoveDropAnticipationRect();
394 _RemoveDropAnticipationRect();
395 BListView::MouseMoved(where, transit, msg);
396 fDragMessageCopy.what = 0;
400 /*****************************************************************************
401 * DragSortableListView::MouseUp
402 *****************************************************************************/
404 DragSortableListView::MouseUp( BPoint where )
407 _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
408 // be sure to forget drag message
409 fDragMessageCopy.what = 0;
410 BListView::MouseUp( where );
413 /*****************************************************************************
414 * DragSortableListView::DrawItem
415 *****************************************************************************/
417 DragSortableListView::DrawItem( BListItem *item, BRect itemFrame, bool complete )
419 DrawListItem( this, IndexOf( item ), itemFrame );
422 /*****************************************************************************
423 * DragSortableListView::ModifiersChaned
424 *****************************************************************************/
426 DragSortableListView::ModifiersChanged()
430 GetMouse( &where, &buttons, false );
431 uint32 transit = Bounds().Contains( where ) ? B_INSIDE_VIEW : B_OUTSIDE_VIEW;
432 MouseMoved( where, transit, &fDragMessageCopy );
435 /*****************************************************************************
436 * DragSortableListView::MoveItems
437 *****************************************************************************/
439 DragSortableListView::MoveItems( BList& items, int32 index )
442 // we remove the items while we look at them, the insertion index is decreased
443 // when the items index is lower, so that we insert at the right spot after
446 int32 count = items.CountItems();
447 for ( int32 i = 0; i < count; i++ )
449 BListItem* item = (BListItem*)items.ItemAt( i );
450 int32 removeIndex = IndexOf( item );
451 if ( RemoveItem( item ) && removedItems.AddItem( (void*)item ) )
453 if ( removeIndex < index )
456 // else ??? -> blow up
458 for ( int32 i = 0; BListItem* item = (BListItem*)removedItems.ItemAt( i ); i++ )
460 if ( AddItem( item, index ) )
462 // after we're done, the newly inserted items will be selected
463 Select( index, true );
464 // next items will be inserted after this one
472 /*****************************************************************************
473 * DragSortableListView::CopyItems
474 *****************************************************************************/
476 DragSortableListView::CopyItems( BList& items, int32 index )
479 // by inserting the items after we copied all items first, we avoid
480 // cloning an item we already inserted and messing everything up
481 // in other words, don't touch the list before we know which items
484 int32 count = items.CountItems();
485 for ( int32 i = 0; i < count; i++ )
487 BListItem* item = CloneItem( IndexOf( (BListItem*)items.ItemAt( i ) ) );
488 if ( item && !clonedItems.AddItem( (void*)item ) )
491 for ( int32 i = 0; BListItem* item = (BListItem*)clonedItems.ItemAt( i ); i++ )
493 if ( AddItem( item, index ) )
495 // after we're done, the newly inserted items will be selected
496 Select( index, true );
497 // next items will be inserted after this one
505 /*****************************************************************************
506 * DragSortableListView::RemoveItemList
507 *****************************************************************************/
509 DragSortableListView::RemoveItemList( BList& items )
511 int32 count = items.CountItems();
512 for ( int32 i = 0; i < count; i++ )
514 BListItem* item = (BListItem*)items.ItemAt( i );
515 if ( RemoveItem( item ) )
520 /*****************************************************************************
521 * DragSortableListView::RemoveSelected
522 *****************************************************************************/
524 DragSortableListView::RemoveSelected()
527 for ( int32 i = 0; BListItem* item = ItemAt( CurrentSelection( i ) ); i++ )
528 items.AddItem( (void*)item );
529 RemoveItemList( items );
532 /*****************************************************************************
533 * DragSortableListView::CountSelectedItems
534 *****************************************************************************/
536 DragSortableListView::CountSelectedItems() const
539 while ( CurrentSelection( count ) >= 0 )
544 /*****************************************************************************
545 * DragSortableListView::_SetDropAnticipationRect
546 *****************************************************************************/
548 DragSortableListView::_SetDropAnticipationRect( BRect r )
550 if ( fDropRect != r )
552 if ( fDropRect.IsValid() )
553 Invalidate( fDropRect );
555 if ( fDropRect.IsValid() )
556 Invalidate( fDropRect );
560 /*****************************************************************************
561 * DragSortableListView::_SetDropAnticipationRect
562 *****************************************************************************/
564 DragSortableListView::_SetDropIndex( int32 index )
566 if ( fDropIndex != index )
569 if ( fDropIndex == -1 )
570 _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
573 int32 count = CountItems();
574 if ( fDropIndex == count )
577 if ( BListItem* item = ItemAt( count - 1 ) )
579 r = ItemFrame( count - 1 );
580 r.top = r.bottom + 1.0;
581 r.bottom = r.top + 1.0;
586 r.bottom--; // compensate for scrollbars moved slightly out of window
588 _SetDropAnticipationRect( r );
592 BRect r = ItemFrame( fDropIndex );
593 r.bottom = r.top + 1.0;
594 _SetDropAnticipationRect( r );
600 /*****************************************************************************
601 * DragSortableListView::_RemoveDropAnticipationRect
602 *****************************************************************************/
604 DragSortableListView::_RemoveDropAnticipationRect()
606 _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
611 /*****************************************************************************
613 *****************************************************************************/
614 PlaylistView::PlaylistView( intf_thread_t * _p_intf,
615 BRect frame, InterfaceWindow* mainWindow,
616 BMessage* selectionChangeMessage )
617 : DragSortableListView( frame, "playlist listview",
618 B_MULTIPLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES,
619 B_WILL_DRAW | B_NAVIGABLE | B_PULSE_NEEDED
620 | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE ),
624 fDisplayMode( DISPLAY_PATH ),
625 fMainWindow( mainWindow ),
626 fSelectionChangeMessage( selectionChangeMessage ),
627 fLastClickedItem( NULL )
631 PlaylistView::~PlaylistView()
633 delete fSelectionChangeMessage;
636 /*****************************************************************************
637 * PlaylistView::AttachedToWindow
638 *****************************************************************************/
640 PlaylistView::AttachedToWindow()
642 // get pulse message every two frames
643 Window()->SetPulseRate( 80000 );
646 /*****************************************************************************
647 * PlaylistView::MessageReceived
648 *****************************************************************************/
650 PlaylistView::MessageReceived( BMessage* message)
652 switch ( message->what )
656 if ( message->HasPointer( "list" ) )
658 // message comes from ourself
659 DragSortableListView::MessageReceived( message );
663 // message comes from another app (for example Tracker)
664 message->AddInt32( "drop index", fDropIndex );
665 fMainWindow->PostMessage( message, fMainWindow );
669 DragSortableListView::MessageReceived( message );
674 /*****************************************************************************
675 * PlaylistView::MouseDown
676 *****************************************************************************/
678 PlaylistView::MouseDown( BPoint where )
681 Window()->CurrentMessage()->FindInt32( "clicks", &clicks );
682 bool handled = false;
683 for ( int32 i = 0; PlaylistItem* item = (PlaylistItem*)ItemAt( i ); i++ )
685 BRect r = ItemFrame( i );
686 if ( r.Contains( where ) )
690 // only do something if user clicked the same item twice
691 if ( fLastClickedItem == item )
693 playlist_t * p_playlist = pl_Hold( p_intf );
696 playlist_Goto( p_playlist, i );
697 pl_Release( p_intf );
704 // remember last clicked item
705 fLastClickedItem = item;
706 if ( i == fCurrentIndex )
708 r.right = r.left + TEXT_OFFSET;
709 if ( r.Contains ( where ) )
711 fMainWindow->PostMessage( PAUSE_PLAYBACK );
721 DragSortableListView::MouseDown(where);
724 /*****************************************************************************
725 * PlaylistView::KeyDown
726 *****************************************************************************/
728 PlaylistView::KeyDown( const char* bytes, int32 numBytes )
733 if ( ( bytes[0] == B_BACKSPACE ) || ( bytes[0] == B_DELETE ) )
737 DragSortableListView::KeyDown( bytes, numBytes );
740 /*****************************************************************************
741 * PlaylistView::Pulse
742 *****************************************************************************/
744 PlaylistView::Pulse()
746 if ( fMainWindow->IsStopped() )
750 /*****************************************************************************
751 * PlaylistView::SelectionChanged
752 *****************************************************************************/
754 PlaylistView::SelectionChanged()
756 BLooper* looper = Looper();
757 if ( fSelectionChangeMessage && looper )
759 BMessage message( *fSelectionChangeMessage );
760 looper->PostMessage( &message );
765 /*****************************************************************************
766 * PlaylistView::MoveItems
767 *****************************************************************************/
769 PlaylistView::MoveItems( BList& items, int32 index )
773 // we remove the items while we look at them, the insertion index is decreased
774 // when the items index is lower, so that we insert at the right spot after
776 if ( fVlcWrapper->PlaylistLock() )
780 int32 count = items.CountItems();
781 int32 indexOriginal = index;
782 // remember currently playing item
783 BListItem* playingItem = _PlayingItem();
784 // collect item pointers for removal by index
785 for ( int32 i = 0; i < count; i++ )
787 int32 removeIndex = IndexOf( (BListItem*)items.ItemAt( i ) );
788 void* item = fVlcWrapper->PlaylistItemAt( removeIndex );
789 if ( item && removeItems.AddItem( item ) )
791 if ( removeIndex < index )
794 // else ??? -> blow up
796 // actually remove items using pointers
797 for ( int32 i = 0; i < count; i++ )
799 void* item = fVlcWrapper->PlaylistRemoveItem( removeItems.ItemAt( i ) );
800 if ( item && !removedItems.AddItem( item ) )
803 // add items at index
804 for ( int32 i = 0; void* item = removedItems.ItemAt( i ); i++ )
806 if ( fVlcWrapper->PlaylistAddItem( item, index ) )
807 // next items will be inserted after this one
813 DragSortableListView::MoveItems( items, indexOriginal );
814 // restore currently playing item
815 _SetPlayingIndex( playingItem );
816 // update interface (in case it isn't playing,
817 // there is a chance that it needs to update)
818 fMainWindow->PostMessage( MSG_UPDATE );
819 fVlcWrapper->PlaylistUnlock();
824 /*****************************************************************************
825 * PlaylistView::CopyItems
826 *****************************************************************************/
828 PlaylistView::CopyItems( BList& items, int32 toIndex )
832 // we remove the items while we look at them, the insertion index is decreased
833 // when the items index is lower, so that we insert at the right spot after
835 if ( fVlcWrapper->PlaylistLock() )
838 int32 count = items.CountItems();
839 // remember currently playing item
840 BListItem* playingItem = _PlayingItem();
841 // collect cloned item pointers
842 for ( int32 i = 0; i < count; i++ )
844 int32 index = IndexOf( (BListItem*)items.ItemAt( i ) );
845 void* item = fVlcWrapper->PlaylistItemAt( index );
846 void* cloned = fVlcWrapper->PlaylistCloneItem( item );
847 if ( cloned && !clonedItems.AddItem( cloned ) )
851 // add cloned items at index
852 int32 index = toIndex;
853 for ( int32 i = 0; void* item = clonedItems.ItemAt( i ); i++ )
855 if ( fVlcWrapper->PlaylistAddItem( item, index ) )
856 // next items will be inserted after this one
862 DragSortableListView::CopyItems( items, toIndex );
863 // restore currently playing item
864 _SetPlayingIndex( playingItem );
865 // update interface (in case it isn't playing,
866 // there is a chance that it needs to update)
867 fMainWindow->PostMessage( MSG_UPDATE );
868 fVlcWrapper->PlaylistUnlock();
873 /*****************************************************************************
874 * PlaylistView::RemoveItemList
875 *****************************************************************************/
877 PlaylistView::RemoveItemList( BList& items )
880 if ( fVlcWrapper->PlaylistLock() )
882 // remember currently playing item
883 BListItem* playingItem = _PlayingItem();
884 // collect item pointers for removal
886 int32 count = items.CountItems();
887 for ( int32 i = 0; i < count; i++ )
889 int32 index = IndexOf( (BListItem*)items.ItemAt( i ) );
890 void* item = fVlcWrapper->PlaylistItemAt( index );
891 if ( item && !removeItems.AddItem( item ) )
894 // remove items from playlist
895 count = removeItems.CountItems();
896 for ( int32 i = 0; void* item = removeItems.ItemAt( i ); i++ )
898 fVlcWrapper->PlaylistRemoveItem( item );
901 DragSortableListView::RemoveItemList( items );
902 // restore currently playing item
903 _SetPlayingIndex( playingItem );
904 // update interface (in case it isn't playing,
905 // there is a chance that it needs to update)
906 fMainWindow->PostMessage( MSG_UPDATE );
907 fVlcWrapper->PlaylistUnlock();
912 /*****************************************************************************
913 * PlaylistView::CloneItem
914 *****************************************************************************/
916 PlaylistView::CloneItem( int32 atIndex ) const
918 BListItem* clone = NULL;
919 if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( atIndex ) ) )
920 clone = new PlaylistItem( item->Text() );
924 /*****************************************************************************
925 * PlaylistView::DrawListItem
926 *****************************************************************************/
928 PlaylistView::DrawListItem( BView* owner, int32 index, BRect frame ) const
930 if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( index ) ) )
931 item->Draw( owner, frame, index % 2,
932 fDisplayMode, index == fCurrentIndex, fPlaying );
935 /*****************************************************************************
936 * PlaylistView::MakeDragMessage
937 *****************************************************************************/
939 PlaylistView::MakeDragMessage( BMessage* message ) const
943 message->AddPointer( "list", (void*)this );
945 for ( int32 i = 0; ( index = CurrentSelection( i ) ) >= 0; i++ )
947 message->AddInt32( "index", index );
948 // add refs to message (inter application communication)
949 if ( BStringItem* item = dynamic_cast<BStringItem*>( ItemAt( index ) ) )
952 if ( get_ref_for_path( item->Text(), &ref ) == B_OK )
953 message->AddRef( "refs", &ref );
959 /*****************************************************************************
960 * PlaylistView::SetCurrent
961 *****************************************************************************/
963 PlaylistView::SetCurrent( int32 index )
965 if ( fCurrentIndex != index )
967 InvalidateItem( fCurrentIndex );
968 fCurrentIndex = index;
969 InvalidateItem( fCurrentIndex );
973 /*****************************************************************************
974 * PlaylistView::SetPlaying
975 *****************************************************************************/
977 PlaylistView::SetPlaying( bool playing )
979 if ( fPlaying != playing )
982 InvalidateItem( fCurrentIndex );
986 /*****************************************************************************
987 * PlaylistView::SetPlaying
988 *****************************************************************************/
990 PlaylistView::RebuildList()
992 playlist_t * p_playlist = pl_Hold( p_intf );
996 int32 count = CountItems();
997 while( ( item = RemoveItem( --count ) ) )
1000 // rebuild listview from VLC's playlist
1002 FOREACH_ARRAY( playlist_item_t *p_item, p_playlist->items )
1003 AddItem( new PlaylistItem( p_item->p_input->psz_name ) );
1007 vlc_object_release( p_playlist );
1011 /*****************************************************************************
1012 * PlaylistView::SortReverse
1013 *****************************************************************************/
1015 PlaylistView::SortReverse()
1018 if ( int32 count = CountSelectedItems() )
1020 int32 last = count - 1;
1021 // remember currently playing item
1022 BListItem* playingItem = _PlayingItem();
1023 for ( int32 first = 0; first < count / 2; first++, last-- )
1025 int32 index1 = CurrentSelection( first);
1026 int32 index2 = CurrentSelection( last);
1027 if ( SwapItems( index1, index2 ) )
1029 // index2 > index1, so the list won't get messed up
1030 // if we remove the items in that order
1031 // TODO: Error checking + handling!
1032 void* item2 = fVlcWrapper->PlaylistRemoveItem( index2 );
1033 void* item1 = fVlcWrapper->PlaylistRemoveItem( index1 );
1034 fVlcWrapper->PlaylistAddItem( item2, index1 );
1035 fVlcWrapper->PlaylistAddItem( item1, index2 );
1038 // restore currently playing item
1039 _SetPlayingIndex( playingItem );
1044 /*****************************************************************************
1045 * PlaylistView::SortByPath
1046 *****************************************************************************/
1048 PlaylistView::SortByPath()
1053 /*****************************************************************************
1054 * PlaylistView::SortByName
1055 *****************************************************************************/
1057 PlaylistView::SortByName()
1061 /*****************************************************************************
1062 * PlaylistView::SetDisplayMode
1063 *****************************************************************************/
1065 PlaylistView::SetDisplayMode( uint32 mode )
1067 if ( mode != fDisplayMode )
1069 fDisplayMode = mode;
1074 /*****************************************************************************
1075 * PlaylistView::_PlayingItem
1076 *****************************************************************************/
1078 PlaylistView::_PlayingItem() const
1080 playlist_t * p_playlist = pl_Hold( p_intf );
1087 BListItem * item = ItemAt( p_playlist->i_index );
1088 pl_Release( p_intf );
1092 /*****************************************************************************
1093 * PlaylistView::_SetPlayingIndex
1094 *****************************************************************************/
1096 PlaylistView::_SetPlayingIndex( BListItem* playingItem )
1098 for ( int32 i = 0; BListItem* item = ItemAt( i ); i++ )
1100 if ( item == playingItem )
1102 playlist_t * p_playlist = pl_Hold( p_intf );
1109 playlist_Goto( p_playlist, i );
1112 pl_Release( p_intf );