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 *****************************************************************************/
34 #include <vlc_interface.h>
36 #include "InterfaceWindow.h"
37 #include "ListViews.h"
40 #define MAX_DRAG_HEIGHT 200.0
42 #define TEXT_OFFSET 20.0
44 /*****************************************************************************
46 *****************************************************************************/
47 PlaylistItem::PlaylistItem( const char *name )
48 : BStringItem( name ),
52 if ( get_ref_for_path( name, &ref) == B_OK )
53 fName.SetTo( ref.name );
56 PlaylistItem::~PlaylistItem()
60 /*****************************************************************************
61 * PlaylistItem::DrawItem
62 *****************************************************************************/
64 PlaylistItem::Draw( BView *owner, BRect frame, bool tintedLine,
65 uint32 mode, bool active, bool playing )
67 rgb_color color = (rgb_color){ 255, 255, 255, 255 };
69 color = tint_color( color, 1.04 );
72 color = tint_color( color, B_DARKEN_2_TINT );
73 owner->SetLowColor( color );
74 owner->FillRect( frame, B_SOLID_LOW );
76 owner->SetHighColor( 0, 0, 0, 255 );
78 owner->GetFontHeight( &fh );
79 const char* text = Text();
83 if ( fName.CountChars() > 0 )
84 text = fName.String();
90 BString truncatedString( text );
91 owner->TruncateString( &truncatedString, B_TRUNCATE_MIDDLE,
92 frame.Width() - TEXT_OFFSET - 4.0 );
93 owner->DrawString( truncatedString.String(),
94 BPoint( frame.left + TEXT_OFFSET,
95 frame.top + fh.ascent + 1.0 ) );
99 rgb_color black = (rgb_color){ 0, 0, 0, 255 };
100 rgb_color green = (rgb_color){ 0, 255, 0, 255 };
101 BRect r( 0.0, 0.0, 10.0, 10.0 );
102 r.OffsetTo( frame.left + 4.0,
103 ceilf( ( frame.top + frame.bottom ) / 2.0 ) - 5.0 );
105 green = tint_color( color, B_DARKEN_1_TINT );
106 rgb_color lightGreen = tint_color( green, B_LIGHTEN_2_TINT );
107 rgb_color darkGreen = tint_color( green, B_DARKEN_2_TINT );
109 arrow[0] = r.LeftTop();
110 arrow[1] = r.LeftBottom();
111 arrow[2].x = r.right;
112 arrow[2].y = ( r.top + r.bottom ) / 2.0;
113 owner->BeginLineArray( 6 );
115 owner->AddLine( arrow[0], arrow[1], black );
116 owner->AddLine( BPoint( arrow[1].x + 1.0, arrow[1].y - 1.0 ),
118 owner->AddLine( arrow[0], arrow[2], black );
125 // highlights and shadow
126 owner->AddLine( arrow[1], arrow[2], darkGreen );
127 owner->AddLine( arrow[0], arrow[2], lightGreen );
128 owner->AddLine( arrow[0], arrow[1], lightGreen );
129 owner->EndLineArray();
136 owner->SetHighColor( green );
137 owner->FillPolygon( arrow, 3 );
141 /*****************************************************************************
142 * DragSortableListView class
143 *****************************************************************************/
144 DragSortableListView::DragSortableListView( BRect frame, const char* name,
145 list_view_type type, uint32 resizingMode,
147 : BListView( frame, name, type, resizingMode, flags ),
148 fDropRect( 0.0, 0.0, -1.0, -1.0 ),
151 SetViewColor( B_TRANSPARENT_32_BIT );
154 DragSortableListView::~DragSortableListView()
158 /*****************************************************************************
159 * DragSortableListView::Draw
160 *****************************************************************************/
162 DragSortableListView::Draw( BRect updateRect )
164 int32 firstIndex = IndexOf( updateRect.LeftTop() );
165 int32 lastIndex = IndexOf( updateRect.RightBottom() );
166 if ( firstIndex >= 0 )
168 if ( lastIndex < firstIndex )
169 lastIndex = CountItems() - 1;
170 // update rect contains items
171 BRect r( updateRect );
172 for ( int32 i = firstIndex; i <= lastIndex; i++)
175 DrawListItem( this, i, r );
177 updateRect.top = r.bottom + 1.0;
178 if ( updateRect.IsValid() )
180 SetLowColor( 255, 255, 255, 255 );
181 FillRect( updateRect, B_SOLID_LOW );
186 SetLowColor( 255, 255, 255, 255 );
187 FillRect( updateRect, B_SOLID_LOW );
189 // drop anticipation indication
190 if ( fDropRect.IsValid() )
192 SetHighColor( 255, 0, 0, 255 );
193 StrokeRect( fDropRect );
197 /*****************************************************************************
198 * DragSortableListView::InitiateDrag
199 *****************************************************************************/
201 DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
203 bool success = false;
204 BListItem* item = ItemAt( CurrentSelection( 0 ) );
207 // workarround a timing problem
209 item = ItemAt( index );
213 // create drag message
214 BMessage msg( B_SIMPLE_DATA );
215 MakeDragMessage( &msg );
216 // figure out drag rect
217 float width = Bounds().Width();
218 BRect dragRect(0.0, 0.0, width, -1.0);
219 // figure out, how many items fit into our bitmap
222 for (numItems = 0; BListItem* item = ItemAt( CurrentSelection( numItems ) ); numItems++) {
223 dragRect.bottom += ceilf( item->Height() ) + 1.0;
224 if ( dragRect.Height() > MAX_DRAG_HEIGHT ) {
226 dragRect.bottom = MAX_DRAG_HEIGHT;
231 BBitmap* dragBitmap = new BBitmap( dragRect, B_RGB32, true );
232 if ( dragBitmap && dragBitmap->IsValid() ) {
233 if ( BView *v = new BView( dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW ) ) {
234 dragBitmap->AddChild( v );
236 BRect itemBounds( dragRect) ;
237 itemBounds.bottom = 0.0;
238 // let all selected items, that fit into our drag_bitmap, draw
239 for ( int32 i = 0; i < numItems; i++ ) {
240 int32 index = CurrentSelection( i );
241 BListItem* item = ItemAt( index );
242 itemBounds.bottom = itemBounds.top + ceilf( item->Height() );
243 if ( itemBounds.bottom > dragRect.bottom )
244 itemBounds.bottom = dragRect.bottom;
245 DrawListItem( v, index, itemBounds );
246 itemBounds.top = itemBounds.bottom + 1.0;
248 // make a black frame arround the edge
249 v->SetHighColor( 0, 0, 0, 255 );
250 v->StrokeRect( v->Bounds() );
253 uint8 *bits = (uint8 *)dragBitmap->Bits();
254 int32 height = (int32)dragBitmap->Bounds().Height() + 1;
255 int32 width = (int32)dragBitmap->Bounds().Width() + 1;
256 int32 bpr = dragBitmap->BytesPerRow();
259 for ( int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr ) {
260 uint8 *line = bits + 3;
261 for (uint8 *end = line + 4 * width; line < end; line += 4)
264 for ( int32 y = height - ALPHA / 2; y < height; y++, bits += bpr ) {
265 uint8 *line = bits + 3;
266 for (uint8 *end = line + 4 * width; line < end; line += 4)
267 *line = (height - y) << 1;
270 for ( int32 y = 0; y < height; y++, bits += bpr ) {
271 uint8 *line = bits + 3;
272 for (uint8 *end = line + 4 * width; line < end; line += 4)
276 dragBitmap->Unlock();
281 DragMessage( &msg, dragBitmap, B_OP_ALPHA, BPoint( 0.0, 0.0 ) );
284 DragMessage( &msg, dragRect.OffsetToCopy( point ), this );
290 /*****************************************************************************
291 * DragSortableListView::WindowActivated
292 *****************************************************************************/
294 DragSortableListView::WindowActivated( bool active )
296 // workarround for buggy focus indication of BScrollView
297 if ( BView* view = Parent() )
301 /*****************************************************************************
302 * DragSortableListView::MessageReceived
303 *****************************************************************************/
305 DragSortableListView::MessageReceived(BMessage* message)
307 switch ( message->what )
309 case B_MODIFIERS_CHANGED:
314 DragSortableListView *list = NULL;
315 if ( message->FindPointer( "list", (void **)&list ) == B_OK
318 int32 count = CountItems();
319 if ( fDropIndex < 0 || fDropIndex > count )
323 for ( int32 i = 0; message->FindInt32( "index", i, &index ) == B_OK; i++ )
324 if ( BListItem* item = ItemAt(index) )
325 items.AddItem( (void*)item );
326 if ( items.CountItems() > 0 )
328 if ( modifiers() & B_SHIFT_KEY )
329 CopyItems( items, fDropIndex );
331 MoveItems( items, fDropIndex );
338 BListView::MessageReceived( message );
343 /*****************************************************************************
344 * DragSortableListView::MouseMoved
345 *****************************************************************************/
347 DragSortableListView::MouseMoved(BPoint where, uint32 transit, const BMessage *msg)
349 if ( msg && ( msg->what == B_SIMPLE_DATA || msg->what == MSG_SOUNDPLAY ) )
351 bool replaceAll = !msg->HasPointer("list") && !(modifiers() & B_SHIFT_KEY);
355 // remember drag message
356 // this is needed to react on modifier changes
357 fDragMessageCopy = *msg;
363 r.bottom--; // compensate for scrollbar offset
364 _SetDropAnticipationRect( r );
369 // offset where by half of item height
370 BRect r( ItemFrame( 0 ) );
371 where.y += r.Height() / 2.0;
373 int32 index = IndexOf( where );
375 index = CountItems();
376 _SetDropIndex( index );
381 // forget drag message
382 fDragMessageCopy.what = 0;
384 _RemoveDropAnticipationRect();
390 _RemoveDropAnticipationRect();
391 BListView::MouseMoved(where, transit, msg);
392 fDragMessageCopy.what = 0;
396 /*****************************************************************************
397 * DragSortableListView::MouseUp
398 *****************************************************************************/
400 DragSortableListView::MouseUp( BPoint where )
403 _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
404 // be sure to forget drag message
405 fDragMessageCopy.what = 0;
406 BListView::MouseUp( where );
409 /*****************************************************************************
410 * DragSortableListView::DrawItem
411 *****************************************************************************/
413 DragSortableListView::DrawItem( BListItem *item, BRect itemFrame, bool complete )
415 DrawListItem( this, IndexOf( item ), itemFrame );
418 /*****************************************************************************
419 * DragSortableListView::ModifiersChaned
420 *****************************************************************************/
422 DragSortableListView::ModifiersChanged()
426 GetMouse( &where, &buttons, false );
427 uint32 transit = Bounds().Contains( where ) ? B_INSIDE_VIEW : B_OUTSIDE_VIEW;
428 MouseMoved( where, transit, &fDragMessageCopy );
431 /*****************************************************************************
432 * DragSortableListView::MoveItems
433 *****************************************************************************/
435 DragSortableListView::MoveItems( BList& items, int32 index )
438 // we remove the items while we look at them, the insertion index is decreased
439 // when the items index is lower, so that we insert at the right spot after
442 int32 count = items.CountItems();
443 for ( int32 i = 0; i < count; i++ )
445 BListItem* item = (BListItem*)items.ItemAt( i );
446 int32 removeIndex = IndexOf( item );
447 if ( RemoveItem( item ) && removedItems.AddItem( (void*)item ) )
449 if ( removeIndex < index )
452 // else ??? -> blow up
454 for ( int32 i = 0; BListItem* item = (BListItem*)removedItems.ItemAt( i ); i++ )
456 if ( AddItem( item, index ) )
458 // after we're done, the newly inserted items will be selected
459 Select( index, true );
460 // next items will be inserted after this one
468 /*****************************************************************************
469 * DragSortableListView::CopyItems
470 *****************************************************************************/
472 DragSortableListView::CopyItems( BList& items, int32 index )
475 // by inserting the items after we copied all items first, we avoid
476 // cloning an item we already inserted and messing everything up
477 // in other words, don't touch the list before we know which items
480 int32 count = items.CountItems();
481 for ( int32 i = 0; i < count; i++ )
483 BListItem* item = CloneItem( IndexOf( (BListItem*)items.ItemAt( i ) ) );
484 if ( item && !clonedItems.AddItem( (void*)item ) )
487 for ( int32 i = 0; BListItem* item = (BListItem*)clonedItems.ItemAt( i ); i++ )
489 if ( AddItem( item, index ) )
491 // after we're done, the newly inserted items will be selected
492 Select( index, true );
493 // next items will be inserted after this one
501 /*****************************************************************************
502 * DragSortableListView::RemoveItemList
503 *****************************************************************************/
505 DragSortableListView::RemoveItemList( BList& items )
507 int32 count = items.CountItems();
508 for ( int32 i = 0; i < count; i++ )
510 BListItem* item = (BListItem*)items.ItemAt( i );
511 if ( RemoveItem( item ) )
516 /*****************************************************************************
517 * DragSortableListView::RemoveSelected
518 *****************************************************************************/
520 DragSortableListView::RemoveSelected()
523 for ( int32 i = 0; BListItem* item = ItemAt( CurrentSelection( i ) ); i++ )
524 items.AddItem( (void*)item );
525 RemoveItemList( items );
528 /*****************************************************************************
529 * DragSortableListView::CountSelectedItems
530 *****************************************************************************/
532 DragSortableListView::CountSelectedItems() const
535 while ( CurrentSelection( count ) >= 0 )
540 /*****************************************************************************
541 * DragSortableListView::_SetDropAnticipationRect
542 *****************************************************************************/
544 DragSortableListView::_SetDropAnticipationRect( BRect r )
546 if ( fDropRect != r )
548 if ( fDropRect.IsValid() )
549 Invalidate( fDropRect );
551 if ( fDropRect.IsValid() )
552 Invalidate( fDropRect );
556 /*****************************************************************************
557 * DragSortableListView::_SetDropAnticipationRect
558 *****************************************************************************/
560 DragSortableListView::_SetDropIndex( int32 index )
562 if ( fDropIndex != index )
565 if ( fDropIndex == -1 )
566 _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
569 int32 count = CountItems();
570 if ( fDropIndex == count )
573 if ( BListItem* item = ItemAt( count - 1 ) )
575 r = ItemFrame( count - 1 );
576 r.top = r.bottom + 1.0;
577 r.bottom = r.top + 1.0;
582 r.bottom--; // compensate for scrollbars moved slightly out of window
584 _SetDropAnticipationRect( r );
588 BRect r = ItemFrame( fDropIndex );
589 r.bottom = r.top + 1.0;
590 _SetDropAnticipationRect( r );
596 /*****************************************************************************
597 * DragSortableListView::_RemoveDropAnticipationRect
598 *****************************************************************************/
600 DragSortableListView::_RemoveDropAnticipationRect()
602 _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
607 /*****************************************************************************
609 *****************************************************************************/
610 PlaylistView::PlaylistView( intf_thread_t * _p_intf,
611 BRect frame, InterfaceWindow* mainWindow,
612 BMessage* selectionChangeMessage )
613 : DragSortableListView( frame, "playlist listview",
614 B_MULTIPLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES,
615 B_WILL_DRAW | B_NAVIGABLE | B_PULSE_NEEDED
616 | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE ),
620 fDisplayMode( DISPLAY_PATH ),
621 fMainWindow( mainWindow ),
622 fSelectionChangeMessage( selectionChangeMessage ),
623 fLastClickedItem( NULL )
627 PlaylistView::~PlaylistView()
629 delete fSelectionChangeMessage;
632 /*****************************************************************************
633 * PlaylistView::AttachedToWindow
634 *****************************************************************************/
636 PlaylistView::AttachedToWindow()
638 // get pulse message every two frames
639 Window()->SetPulseRate( 80000 );
642 /*****************************************************************************
643 * PlaylistView::MessageReceived
644 *****************************************************************************/
646 PlaylistView::MessageReceived( BMessage* message)
648 switch ( message->what )
652 if ( message->HasPointer( "list" ) )
654 // message comes from ourself
655 DragSortableListView::MessageReceived( message );
659 // message comes from another app (for example Tracker)
660 message->AddInt32( "drop index", fDropIndex );
661 fMainWindow->PostMessage( message, fMainWindow );
665 DragSortableListView::MessageReceived( message );
670 /*****************************************************************************
671 * PlaylistView::MouseDown
672 *****************************************************************************/
674 PlaylistView::MouseDown( BPoint where )
677 Window()->CurrentMessage()->FindInt32( "clicks", &clicks );
678 bool handled = false;
679 for ( int32 i = 0; PlaylistItem* item = (PlaylistItem*)ItemAt( i ); i++ )
681 BRect r = ItemFrame( i );
682 if ( r.Contains( where ) )
686 // only do something if user clicked the same item twice
687 if ( fLastClickedItem == item )
689 playlist_t * p_playlist;
690 p_playlist = (playlist_t *) vlc_object_find( p_intf,
691 VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
694 playlist_Goto( p_playlist, i );
695 vlc_object_release( p_playlist );
702 // remember last clicked item
703 fLastClickedItem = item;
704 if ( i == fCurrentIndex )
706 r.right = r.left + TEXT_OFFSET;
707 if ( r.Contains ( where ) )
709 fMainWindow->PostMessage( PAUSE_PLAYBACK );
719 DragSortableListView::MouseDown(where);
722 /*****************************************************************************
723 * PlaylistView::KeyDown
724 *****************************************************************************/
726 PlaylistView::KeyDown( const char* bytes, int32 numBytes )
731 if ( ( bytes[0] == B_BACKSPACE ) || ( bytes[0] == B_DELETE ) )
735 DragSortableListView::KeyDown( bytes, numBytes );
738 /*****************************************************************************
739 * PlaylistView::Pulse
740 *****************************************************************************/
742 PlaylistView::Pulse()
744 if ( fMainWindow->IsStopped() )
748 /*****************************************************************************
749 * PlaylistView::SelectionChanged
750 *****************************************************************************/
752 PlaylistView::SelectionChanged()
754 BLooper* looper = Looper();
755 if ( fSelectionChangeMessage && looper )
757 BMessage message( *fSelectionChangeMessage );
758 looper->PostMessage( &message );
763 /*****************************************************************************
764 * PlaylistView::MoveItems
765 *****************************************************************************/
767 PlaylistView::MoveItems( BList& items, int32 index )
771 // we remove the items while we look at them, the insertion index is decreased
772 // when the items index is lower, so that we insert at the right spot after
774 if ( fVlcWrapper->PlaylistLock() )
778 int32 count = items.CountItems();
779 int32 indexOriginal = index;
780 // remember currently playing item
781 BListItem* playingItem = _PlayingItem();
782 // collect item pointers for removal by index
783 for ( int32 i = 0; i < count; i++ )
785 int32 removeIndex = IndexOf( (BListItem*)items.ItemAt( i ) );
786 void* item = fVlcWrapper->PlaylistItemAt( removeIndex );
787 if ( item && removeItems.AddItem( item ) )
789 if ( removeIndex < index )
792 // else ??? -> blow up
794 // actually remove items using pointers
795 for ( int32 i = 0; i < count; i++ )
797 void* item = fVlcWrapper->PlaylistRemoveItem( removeItems.ItemAt( i ) );
798 if ( item && !removedItems.AddItem( item ) )
801 // add items at index
802 for ( int32 i = 0; void* item = removedItems.ItemAt( i ); i++ )
804 if ( fVlcWrapper->PlaylistAddItem( item, index ) )
805 // next items will be inserted after this one
811 DragSortableListView::MoveItems( items, indexOriginal );
812 // restore currently playing item
813 _SetPlayingIndex( playingItem );
814 // update interface (in case it isn't playing,
815 // there is a chance that it needs to update)
816 fMainWindow->PostMessage( MSG_UPDATE );
817 fVlcWrapper->PlaylistUnlock();
822 /*****************************************************************************
823 * PlaylistView::CopyItems
824 *****************************************************************************/
826 PlaylistView::CopyItems( BList& items, int32 toIndex )
830 // we remove the items while we look at them, the insertion index is decreased
831 // when the items index is lower, so that we insert at the right spot after
833 if ( fVlcWrapper->PlaylistLock() )
836 int32 count = items.CountItems();
837 // remember currently playing item
838 BListItem* playingItem = _PlayingItem();
839 // collect cloned item pointers
840 for ( int32 i = 0; i < count; i++ )
842 int32 index = IndexOf( (BListItem*)items.ItemAt( i ) );
843 void* item = fVlcWrapper->PlaylistItemAt( index );
844 void* cloned = fVlcWrapper->PlaylistCloneItem( item );
845 if ( cloned && !clonedItems.AddItem( cloned ) )
849 // add cloned items at index
850 int32 index = toIndex;
851 for ( int32 i = 0; void* item = clonedItems.ItemAt( i ); i++ )
853 if ( fVlcWrapper->PlaylistAddItem( item, index ) )
854 // next items will be inserted after this one
860 DragSortableListView::CopyItems( items, toIndex );
861 // restore currently playing item
862 _SetPlayingIndex( playingItem );
863 // update interface (in case it isn't playing,
864 // there is a chance that it needs to update)
865 fMainWindow->PostMessage( MSG_UPDATE );
866 fVlcWrapper->PlaylistUnlock();
871 /*****************************************************************************
872 * PlaylistView::RemoveItemList
873 *****************************************************************************/
875 PlaylistView::RemoveItemList( BList& items )
878 if ( fVlcWrapper->PlaylistLock() )
880 // remember currently playing item
881 BListItem* playingItem = _PlayingItem();
882 // collect item pointers for removal
884 int32 count = items.CountItems();
885 for ( int32 i = 0; i < count; i++ )
887 int32 index = IndexOf( (BListItem*)items.ItemAt( i ) );
888 void* item = fVlcWrapper->PlaylistItemAt( index );
889 if ( item && !removeItems.AddItem( item ) )
892 // remove items from playlist
893 count = removeItems.CountItems();
894 for ( int32 i = 0; void* item = removeItems.ItemAt( i ); i++ )
896 fVlcWrapper->PlaylistRemoveItem( item );
899 DragSortableListView::RemoveItemList( items );
900 // restore currently playing item
901 _SetPlayingIndex( playingItem );
902 // update interface (in case it isn't playing,
903 // there is a chance that it needs to update)
904 fMainWindow->PostMessage( MSG_UPDATE );
905 fVlcWrapper->PlaylistUnlock();
910 /*****************************************************************************
911 * PlaylistView::CloneItem
912 *****************************************************************************/
914 PlaylistView::CloneItem( int32 atIndex ) const
916 BListItem* clone = NULL;
917 if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( atIndex ) ) )
918 clone = new PlaylistItem( item->Text() );
922 /*****************************************************************************
923 * PlaylistView::DrawListItem
924 *****************************************************************************/
926 PlaylistView::DrawListItem( BView* owner, int32 index, BRect frame ) const
928 if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( index ) ) )
929 item->Draw( owner, frame, index % 2,
930 fDisplayMode, index == fCurrentIndex, fPlaying );
933 /*****************************************************************************
934 * PlaylistView::MakeDragMessage
935 *****************************************************************************/
937 PlaylistView::MakeDragMessage( BMessage* message ) const
941 message->AddPointer( "list", (void*)this );
943 for ( int32 i = 0; ( index = CurrentSelection( i ) ) >= 0; i++ )
945 message->AddInt32( "index", index );
946 // add refs to message (inter application communication)
947 if ( BStringItem* item = dynamic_cast<BStringItem*>( ItemAt( index ) ) )
950 if ( get_ref_for_path( item->Text(), &ref ) == B_OK )
951 message->AddRef( "refs", &ref );
957 /*****************************************************************************
958 * PlaylistView::SetCurrent
959 *****************************************************************************/
961 PlaylistView::SetCurrent( int32 index )
963 if ( fCurrentIndex != index )
965 InvalidateItem( fCurrentIndex );
966 fCurrentIndex = index;
967 InvalidateItem( fCurrentIndex );
971 /*****************************************************************************
972 * PlaylistView::SetPlaying
973 *****************************************************************************/
975 PlaylistView::SetPlaying( bool playing )
977 if ( fPlaying != playing )
980 InvalidateItem( fCurrentIndex );
984 /*****************************************************************************
985 * PlaylistView::SetPlaying
986 *****************************************************************************/
988 PlaylistView::RebuildList()
990 playlist_t * p_playlist = pl_Yield( p_intf );
994 int32 count = CountItems();
995 while( ( item = RemoveItem( --count ) ) )
998 // rebuild listview from VLC's playlist
1000 FOREACH_ARRAY( playlist_item_t *p_item, p_playlist->items )
1001 AddItem( new PlaylistItem( p_item->p_input->psz_name ) );
1005 vlc_object_release( p_playlist );
1009 /*****************************************************************************
1010 * PlaylistView::SortReverse
1011 *****************************************************************************/
1013 PlaylistView::SortReverse()
1016 if ( int32 count = CountSelectedItems() )
1018 int32 last = count - 1;
1019 // remember currently playing item
1020 BListItem* playingItem = _PlayingItem();
1021 for ( int32 first = 0; first < count / 2; first++, last-- )
1023 int32 index1 = CurrentSelection( first);
1024 int32 index2 = CurrentSelection( last);
1025 if ( SwapItems( index1, index2 ) )
1027 // index2 > index1, so the list won't get messed up
1028 // if we remove the items in that order
1029 // TODO: Error checking + handling!
1030 void* item2 = fVlcWrapper->PlaylistRemoveItem( index2 );
1031 void* item1 = fVlcWrapper->PlaylistRemoveItem( index1 );
1032 fVlcWrapper->PlaylistAddItem( item2, index1 );
1033 fVlcWrapper->PlaylistAddItem( item1, index2 );
1036 // restore currently playing item
1037 _SetPlayingIndex( playingItem );
1042 /*****************************************************************************
1043 * PlaylistView::SortByPath
1044 *****************************************************************************/
1046 PlaylistView::SortByPath()
1051 /*****************************************************************************
1052 * PlaylistView::SortByName
1053 *****************************************************************************/
1055 PlaylistView::SortByName()
1059 /*****************************************************************************
1060 * PlaylistView::SetDisplayMode
1061 *****************************************************************************/
1063 PlaylistView::SetDisplayMode( uint32 mode )
1065 if ( mode != fDisplayMode )
1067 fDisplayMode = mode;
1072 /*****************************************************************************
1073 * PlaylistView::_PlayingItem
1074 *****************************************************************************/
1076 PlaylistView::_PlayingItem() const
1078 playlist_t * p_playlist;
1079 p_playlist = (playlist_t *) vlc_object_find( p_intf,
1080 VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
1087 BListItem * item = ItemAt( p_playlist->i_index );
1088 vlc_object_release( p_playlist );
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;
1103 p_playlist = (playlist_t *) vlc_object_find( p_intf,
1104 VLC_OBJECT_PLAYLIST, FIND_ANYWHERE );
1111 playlist_Goto( p_playlist, i );
1114 vlc_object_release( p_playlist );