]> git.sesse.net Git - vlc/commitdiff
Forgot to `cvs add' ;)
authorEric Petit <titer@videolan.org>
Sun, 29 Sep 2002 12:06:08 +0000 (12:06 +0000)
committerEric Petit <titer@videolan.org>
Sun, 29 Sep 2002 12:06:08 +0000 (12:06 +0000)
plugins/beos/ListViews.cpp [new file with mode: 0644]
plugins/beos/ListViews.h [new file with mode: 0644]

diff --git a/plugins/beos/ListViews.cpp b/plugins/beos/ListViews.cpp
new file mode 100644 (file)
index 0000000..843ae49
--- /dev/null
@@ -0,0 +1,641 @@
+/*****************************************************************************
+ * ListViews.h: BeOS interface list view class implementation
+ *****************************************************************************
+ * Copyright (C) 1999, 2000, 2001 VideoLAN
+ * $Id: ListViews.cpp,v 1.1.2.1 2002/09/29 12:06:08 titer Exp $
+ *
+ * Authors: Stephan Aßmus <stippi@yellowbites.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+#include <stdio.h>
+
+#include <Bitmap.h>
+#include <String.h>
+
+extern "C"
+{
+#include <videolan/vlc.h>
+
+#include "stream_control.h"
+
+#include "interface.h"
+#include "input_ext-intf.h"
+}
+
+#include "InterfaceWindow.h"
+#include "ListViews.h"
+#include "MsgVals.h"
+#include "intf_vlc_wrapper.h"
+
+
+#define MAX_DRAG_HEIGHT                200.0
+#define ALPHA                          170
+#define TEXT_OFFSET                    20.0
+
+/*****************************************************************************
+ * PlaylistItem class
+ *****************************************************************************/
+PlaylistItem::PlaylistItem( const char *name )
+       : BStringItem( name )
+{
+}
+
+PlaylistItem::~PlaylistItem()
+{
+}
+
+/*****************************************************************************
+ * PlaylistItem::DrawItem
+ *****************************************************************************/
+void
+PlaylistItem::Draw( BView *owner, BRect frame, bool tintedLine,
+                                       bool active, bool playing )
+{
+       rgb_color color = (rgb_color){ 255, 255, 255, 255 };
+       if ( tintedLine )
+               color = tint_color( color, 1.04 );
+       // background
+       if ( IsSelected() )
+               color = tint_color( color, B_DARKEN_2_TINT );
+       owner->SetLowColor( color );
+       owner->FillRect( frame, B_SOLID_LOW );
+       // label
+       owner->SetHighColor( 0, 0, 0, 255 );
+       font_height fh;
+       owner->GetFontHeight( &fh );
+       BString truncatedString( Text() );
+       owner->TruncateString( &truncatedString, B_TRUNCATE_MIDDLE,
+                                                  frame.Width() - TEXT_OFFSET - 4.0 );
+       owner->DrawString( truncatedString.String(),
+                                          BPoint( frame.left + TEXT_OFFSET,
+                                                          frame.top + fh.ascent + 1.0 ) );
+       // playmark
+       if ( active )
+       {
+               rgb_color black = (rgb_color){ 0, 0, 0, 255 };
+               rgb_color green = (rgb_color){ 0, 255, 0, 255 };
+               BRect r( 0.0, 0.0, 10.0, 10.0 );
+               r.OffsetTo( frame.left + 4.0,
+                                       ceilf( ( frame.top + frame.bottom ) / 2.0 ) - 5.0 );
+               if ( !playing )
+                       green = tint_color( color, B_DARKEN_1_TINT );
+               rgb_color lightGreen = tint_color( green, B_LIGHTEN_2_TINT );
+               rgb_color darkGreen = tint_color( green, B_DARKEN_2_TINT );
+               BPoint arrow[3];
+               arrow[0] = r.LeftTop();
+               arrow[1] = r.LeftBottom();
+               arrow[2].x = r.right;
+               arrow[2].y = ( r.top + r.bottom ) / 2.0;
+               owner->BeginLineArray( 6 );
+                       // black outline
+                       owner->AddLine( arrow[0], arrow[1], black );
+                       owner->AddLine( BPoint( arrow[1].x + 1.0, arrow[1].y - 1.0 ),
+                                                       arrow[2], black );
+                       owner->AddLine( arrow[0], arrow[2], black );
+                       // inset arrow
+                       arrow[0].x += 1.0;
+                       arrow[0].y += 2.0;
+                       arrow[1].x += 1.0;
+                       arrow[1].y -= 2.0;
+                       arrow[2].x -= 2.0;
+                       // highlights and shadow
+                       owner->AddLine( arrow[1], arrow[2], darkGreen );
+                       owner->AddLine( arrow[0], arrow[2], lightGreen );
+                       owner->AddLine( arrow[0], arrow[1], lightGreen );
+               owner->EndLineArray();
+               // fill green
+               arrow[0].x += 1.0;
+               arrow[0].y += 1.0;
+               arrow[1].x += 1.0;
+               arrow[1].y -= 1.0;
+               arrow[2].x -= 2.0;
+               owner->SetHighColor( green );
+               owner->FillPolygon( arrow, 3 );
+       }
+}
+
+/*****************************************************************************
+ * DragSortableListView class
+ *****************************************************************************/
+DragSortableListView::DragSortableListView( BRect frame, const char* name,
+                                                                                       list_view_type type, uint32 resizingMode,
+                                                                                       uint32 flags )
+       : BListView( frame, name, type, resizingMode, flags ),
+         fDropIndex( -1 )
+{
+       SetViewColor( B_TRANSPARENT_32_BIT );
+}
+
+DragSortableListView::~DragSortableListView()
+{
+}
+
+/*****************************************************************************
+ * DragSortableListView::Draw
+ *****************************************************************************/
+void
+DragSortableListView::Draw( BRect updateRect )
+{
+       int32 firstIndex = IndexOf( updateRect.LeftTop() );
+       int32 lastIndex = IndexOf( updateRect.RightBottom() );
+       if ( firstIndex >= 0 )
+       {
+               if ( lastIndex < firstIndex )
+                       lastIndex = CountItems() - 1;
+               // update rect contains items
+               BRect r( updateRect );
+               for ( int32 i = firstIndex; i <= lastIndex; i++)
+               {
+                       r = ItemFrame( i );
+                       DrawListItem( this, i, r );
+               }
+               updateRect.top = r.bottom + 1.0;
+               if ( updateRect.IsValid() )
+               {
+                       SetLowColor( 255, 255, 255, 255 );
+                       FillRect( updateRect, B_SOLID_LOW );
+               }
+       }
+       else
+       {
+               SetLowColor( 255, 255, 255, 255 );
+               FillRect( updateRect, B_SOLID_LOW );
+       }
+}
+
+/*****************************************************************************
+ * DragSortableListView::InitiateDrag
+ *****************************************************************************/
+bool
+DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
+{
+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( B_SIMPLE_DATA );
+               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 += item->Height();
+                       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 + item->Height() - 1.0;
+                                       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();
+                               success = true;
+                       }
+               }
+               if (success)
+                       DragMessage( &msg, dragBitmap, B_OP_ALPHA, BPoint( 0.0, 0.0 ) );
+               else {
+                       delete dragBitmap;
+                       DragMessage( &msg, dragRect.OffsetToCopy( point ), this );
+               }
+       }
+       return success;
+}
+
+/*****************************************************************************
+ * DragSortableListView::WindowActivated
+ *****************************************************************************/
+void
+DragSortableListView::WindowActivated( bool active )
+{
+       // workarround for buggy focus indication of BScrollView
+       if ( BView* view = Parent() )
+               view->Invalidate();
+}
+
+/*****************************************************************************
+ * DragSortableListView::MessageReceived
+ *****************************************************************************/
+void
+DragSortableListView::MessageReceived(BMessage* message)
+{
+       BListItem *item = NULL;
+       DragSortableListView *list = NULL;
+       if ( message->FindPointer( "list", (void **)&list ) == B_OK
+                && list == this )
+       {
+               int32 count = CountItems();
+               if ( fDropIndex < 0 || fDropIndex > count )
+                       fDropIndex = count;
+               bool copy = ( modifiers() & B_SHIFT_KEY );
+               for ( int32 i = 0; message->FindPointer( "item", i, (void **)&item ) == B_OK; i++ )
+               {
+                       
+                       if ( HasItem( item ) )
+                       {
+                               BListItem* itemToAdd = NULL;
+                               int32 index = IndexOf( item );
+                               if ( copy )
+                               {
+                                       // add cloned item
+                                       itemToAdd = CloneItem( index );
+                                       Deselect( IndexOf( item ) );
+                               }
+                               else
+                               {
+                                       // drag sort
+                                       if ( index < fDropIndex )
+                                               fDropIndex--;
+                                       if ( RemoveItem( item ) )
+                                               itemToAdd = item;
+                               }
+                               if ( itemToAdd )
+                               {
+                                       if ( AddItem( itemToAdd, fDropIndex ) )
+                                               Select( IndexOf( itemToAdd ), true );
+                                       else
+                                               delete itemToAdd;
+                               }
+                       }
+                       fDropIndex++;
+               }
+               fDropIndex = -1;
+       } else
+               BListView::MessageReceived( message );
+}
+
+/*****************************************************************************
+ * DragSortableListView::MouseMoved
+ *****************************************************************************/
+void
+DragSortableListView::MouseMoved(BPoint where, uint32 transit, const BMessage *msg)
+{
+       if ( msg && msg->what == B_SIMPLE_DATA )
+       {
+               switch ( transit )
+               {
+                       case B_ENTERED_VIEW:
+                       {
+                               // draw drop mark
+                               BRect r(ItemFrame(0L));
+                               where.y += r.Height() / 2.0;
+                               int32 count = CountItems();
+                               bool found = false;
+                               for (int32 index = 0; index <= count; index++)
+                               {
+                                       r = ItemFrame(index);
+                                       if (r.Contains(where))
+                                       {
+                                               SetHighColor(255, 0, 0, 255);
+                                               StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
+                                               r.top++;
+                                               StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
+                                               fDropIndex = index;
+                                               found = true;
+                                               break;
+                                       }
+                               }
+                               if (found)
+                                       break;
+                               // mouse is after last item
+                               fDropIndex = count;
+                               r = Bounds();
+                               if (count > 0)
+                                       r.top = ItemFrame(count - 1).bottom + 1.0;
+                               SetHighColor(255, 0, 0, 255);
+                               StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
+                               r.top++;
+                               StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
+                               break;
+                       }
+                       case B_INSIDE_VIEW:
+                       {
+                               // draw drop mark and invalidate previous drop mark
+                               BRect r(ItemFrame(0L));
+                               where.y += r.Height() / 2.0;
+                               int32 count = CountItems();
+                               // mouse still after last item?
+                               if (fDropIndex == count)
+                               {
+                                       r = Bounds();
+                                       if (count > 0)
+                                               r.top = ItemFrame(count - 1).bottom + 1.0;
+                                       if (r.Contains(where))
+                                               break;
+                                       else
+                                       {
+                                               r.bottom = r.top + 2.0;
+                                               Invalidate(r);
+                                       }
+                               }
+                               // mouse still over same item?
+                               if (ItemFrame(fDropIndex).Contains(where))
+                                       break;
+                               else
+                                       InvalidateItem(fDropIndex);
+
+                               // mouse over new item
+                               bool found = false;
+                               for (int32 index = 0; index <= count; index++)
+                               {
+                                       r = ItemFrame(index);
+                                       if (r.Contains(where))
+                                       {
+                                               SetHighColor(255, 0, 0, 255);
+                                               StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
+                                               r.top++;
+                                               StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
+                                               fDropIndex = index;
+                                               found = true;
+                                               break;
+                                       }
+                               }
+                               if (found)
+                                       break;
+                               // mouse is after last item
+                               fDropIndex = count;
+                               r = Bounds();
+                               if (count > 0)
+                                       r.top = ItemFrame(count - 1).bottom + 1.0;
+                               SetHighColor(255, 0, 0, 255);
+                               StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
+                               r.top++;
+                               StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_HIGH);
+                               break;
+                       }
+                       case B_EXITED_VIEW:
+                       {
+                               int32 count = CountItems();
+                               if (count > 0)
+                               {
+                                       if (fDropIndex == count)
+                                       {
+                                               BRect r(Bounds());
+                                               r.top = ItemFrame(count - 1).bottom + 1.0;
+                                               r.bottom = r.top + 2.0;
+                                               Invalidate(r);
+                                       }
+                                       else
+                                               InvalidateItem(fDropIndex);
+                               }
+                               break;
+                       }
+                       case B_OUTSIDE_VIEW:
+                               break;
+               }
+       }
+       else
+               BListView::MouseMoved(where, transit, msg);
+}
+
+/*****************************************************************************
+ * DragSortableListView::MouseUp
+ *****************************************************************************/
+void
+DragSortableListView::MouseUp( BPoint where )
+{
+       // remove drop mark
+       if ( fDropIndex >= 0 && fDropIndex < CountItems() )
+               InvalidateItem( fDropIndex );
+       BListView::MouseUp( where );
+}
+
+/*****************************************************************************
+ * DragSortableListView::DrawItem
+ *****************************************************************************/
+void
+DragSortableListView::DrawItem( BListItem *item, BRect itemFrame, bool complete )
+{
+       DrawListItem( this, IndexOf( item ), itemFrame );
+}
+
+
+/*****************************************************************************
+ * PlaylistView class
+ *****************************************************************************/
+PlaylistView::PlaylistView( BRect frame, InterfaceWindow* mainWindow )
+       : DragSortableListView( frame, "playlist listview",
+                                                       B_MULTIPLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES,
+                                                       B_WILL_DRAW | B_NAVIGABLE | B_PULSE_NEEDED
+                                                       | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE ),
+         fCurrentIndex( -1 ),
+         fPlaying( false ),
+         fMainWindow( mainWindow )
+{
+}
+
+PlaylistView::~PlaylistView()
+{
+}
+
+/*****************************************************************************
+ * PlaylistView::AttachedToWindow
+ *****************************************************************************/
+void
+PlaylistView::AttachedToWindow()
+{
+       // get pulse message every two frames
+       Window()->SetPulseRate(80000);
+}
+
+/*****************************************************************************
+ * PlaylistView::MouseDown
+ *****************************************************************************/
+void
+PlaylistView::MouseDown( BPoint where )
+{
+       int32 clicks = 1;
+       Window()->CurrentMessage()->FindInt32( "clicks", &clicks );
+       bool handled = false;
+       for ( int32 i = 0; PlaylistItem* item = (PlaylistItem*)ItemAt( i ); i++ )
+       {
+               BRect r = ItemFrame( i );
+               if ( r.Contains( where ) )
+               {
+                       if ( clicks == 2 )
+                       {
+                               Intf_VLCWrapper::playlistJumpTo( i );
+                               handled = true;
+                       }
+                       else if ( i == fCurrentIndex )
+                       {
+                               r.right = r.left + TEXT_OFFSET;
+                               if ( r.Contains ( where ) )
+                               {
+                                       fMainWindow->PostMessage( PAUSE_PLAYBACK );
+                                       InvalidateItem( i );
+                                       handled = true;
+                               }
+                       }
+                       break;
+               }
+       }
+       if ( !handled )
+               DragSortableListView::MouseDown(where);
+}
+
+/*****************************************************************************
+ * PlaylistView::KeyDown
+ *****************************************************************************/
+void
+PlaylistView::KeyDown( const char* bytes, int32 numBytes )
+{
+       if (numBytes < 1)
+               return;
+               
+       if ( ( bytes[0] == B_BACKSPACE ) || ( bytes[0] == B_DELETE ) )
+       {
+               int32 i = CurrentSelection();
+               if ( BListItem *item = ItemAt( i ) )
+               {
+/*                     if ( RemoveItem( item ) )
+                       {
+                               delete item;
+                               Select( i + 1 );
+                       }*/
+               }
+       }
+       DragSortableListView::KeyDown( bytes, numBytes );
+}
+
+/*****************************************************************************
+ * PlaylistView::Pulse
+ *****************************************************************************/
+void
+PlaylistView::Pulse()
+{
+       if (fMainWindow->IsStopped())
+               SetPlaying( false );
+}
+
+/*****************************************************************************
+ * PlaylistView::CloneItem
+ *****************************************************************************/
+BListItem*
+PlaylistView::CloneItem( int32 atIndex ) const
+{
+       BListItem* clone = NULL;
+       if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( atIndex ) ) )
+               clone = new PlaylistItem( item->Text() );
+       return clone;
+}
+
+/*****************************************************************************
+ * PlaylistView::DrawListItem
+ *****************************************************************************/
+void
+PlaylistView::DrawListItem( BView* owner, int32 index, BRect frame ) const
+{
+       if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( index ) ) )
+               item->Draw( owner,  frame, index % 2, index == fCurrentIndex, fPlaying );
+}
+
+/*****************************************************************************
+ * PlaylistView::MakeDragMessage
+ *****************************************************************************/
+void
+PlaylistView::MakeDragMessage( BMessage* message ) const
+{
+       if ( message )
+       {
+               message->AddPointer( "list", (void*)this );
+               for ( int32 i = 0; BListItem* item = ItemAt( CurrentSelection( i ) ); i++ )
+                       message->AddPointer( "item", (void*)item );
+       }
+}
+
+/*****************************************************************************
+ * PlaylistView::SetCurrent
+ *****************************************************************************/
+void
+PlaylistView::SetCurrent( int32 index )
+{
+       if ( fCurrentIndex != index )
+       {
+               InvalidateItem( fCurrentIndex );
+               fCurrentIndex = index;
+               InvalidateItem( fCurrentIndex );
+       }
+}
+
+/*****************************************************************************
+ * PlaylistView::SetPlaying
+ *****************************************************************************/
+void
+PlaylistView::SetPlaying( bool playing )
+{
+       if ( fPlaying != playing )
+       {
+               fPlaying = playing;
+               InvalidateItem( fCurrentIndex );
+       }
+}
diff --git a/plugins/beos/ListViews.h b/plugins/beos/ListViews.h
new file mode 100644 (file)
index 0000000..5ed50e2
--- /dev/null
@@ -0,0 +1,115 @@
+/*****************************************************************************
+ * ListViews.h: BeOS interface list view class prototype
+ *****************************************************************************
+ * Copyright (C) 1999, 2000, 2001 VideoLAN
+ * $Id: ListViews.h,v 1.1.2.1 2002/09/29 12:06:08 titer Exp $
+ *
+ * Authors: Stephan Aßmus <stippi@yellowbites.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ *****************************************************************************/
+
+#ifndef LIST_VIEWS_H
+#define LIST_VIEWS_H
+
+#include <ListItem.h>
+#include <ListView.h>
+
+class InterfaceWindow;
+
+// PlaylistItem
+class PlaylistItem : public BStringItem
+{
+ public:
+                                                       PlaylistItem( const char* name );
+               virtual                         ~PlaylistItem();
+
+               virtual void            Draw( BView* owner, BRect frame,
+                                                                 bool tintedLine,
+                                                                 bool active = false,
+                                                                 bool playing = false );
+
+};
+
+// DragSortableListView
+class DragSortableListView : public BListView
+{
+ public:
+                                                       DragSortableListView( BRect frame,
+                                                                                                 const char* name,
+                                                                                                 list_view_type type
+                                                                                                               = B_SINGLE_SELECTION_LIST,
+                                                                                                 uint32 resizingMode
+                                                                                                               = B_FOLLOW_LEFT
+                                                                                                                 | B_FOLLOW_TOP,
+                                                                                                 uint32 flags
+                                                                                                               = B_WILL_DRAW
+                                                                                                                 | B_NAVIGABLE
+                                                                                                                 | B_FRAME_EVENTS );
+       virtual                                 ~DragSortableListView();
+
+                                                       // BListView
+       virtual void                    Draw( BRect updateRect );
+       virtual bool                    InitiateDrag( BPoint point, int32 index,
+                                                                                 bool wasSelected );
+       virtual void                    MessageReceived( BMessage* message );
+       virtual void                    MouseMoved( BPoint where, uint32 transit,
+                                                                               const BMessage* dragMessage );
+       virtual void                    MouseUp( BPoint where );
+       virtual void                    WindowActivated( bool active );
+       virtual void                    DrawItem( BListItem *item, BRect itemFrame,
+                                                                         bool complete = false);
+
+                                                       // DragSortableListView
+       virtual BListItem*              CloneItem( int32 atIndex ) const = 0;
+       virtual void                    DrawListItem( BView* owner, int32 index,
+                                                                                 BRect itemFrame ) const = 0;
+       virtual void                    MakeDragMessage( BMessage* message ) const = 0;
+
+ private:
+       int32                   fDropIndex;
+};
+
+// PlaylistView
+class PlaylistView : public DragSortableListView
+{
+ public:
+                                                       PlaylistView( BRect frame,
+                                                                                 InterfaceWindow* mainWindow );
+                                                       ~PlaylistView();
+
+                                                       // BListView
+       virtual void                    AttachedToWindow();
+       virtual void                    MouseDown( BPoint where );
+       virtual void                    KeyDown( const char* bytes, int32 numBytes );
+       virtual void                    Pulse();
+
+                                                       // DragSortableListView
+       virtual BListItem*              CloneItem( int32 atIndex ) const;
+       virtual void                    DrawListItem( BView* owner, int32 index,
+                                                                                 BRect itemFrame ) const;
+       virtual void                    MakeDragMessage( BMessage* message ) const;
+
+                                                       // PlaylistView
+                       void                    SetCurrent( int32 index );
+                       void                    SetPlaying( bool playing );
+
+ private:
+       int32                                   fCurrentIndex;
+       bool                                    fPlaying;
+       InterfaceWindow*                fMainWindow;
+};
+
+#endif // LIST_VIEWS_H