ListViews.cpp
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:37k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * ListViews.h: BeOS interface list view class implementation
  3.  *****************************************************************************
  4.  * Copyright (C) 1999, 2000, 2001 the VideoLAN team
  5.  * $Id: c3ccc84cf7efab9c4bfb7f92d93c0df5fb6c22b9 $
  6.  *
  7.  * Authors: Stephan Aßmus <stippi@yellowbites.com>
  8.  *
  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.
  13.  *
  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.
  18.  *
  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.  *****************************************************************************/
  23. #if 0
  24. #include <malloc.h>
  25. #include <Bitmap.h>
  26. #include <Entry.h>
  27. #include <String.h>
  28. /* VLC headers */
  29. #ifdef HAVE_CONFIG_H
  30. # include "config.h"
  31. #endif
  32. #include <vlc_common.h>
  33. #include <vlc_interface.h>
  34. #include "InterfaceWindow.h"
  35. #include "ListViews.h"
  36. #include "MsgVals.h"
  37. #define MAX_DRAG_HEIGHT        200.0
  38. #define ALPHA                170
  39. #define TEXT_OFFSET            20.0
  40. /*****************************************************************************
  41.  * PlaylistItem class
  42.  *****************************************************************************/
  43. PlaylistItem::PlaylistItem( const char *name )
  44.     : BStringItem( name ),
  45.       fName( "" )
  46. {
  47.     entry_ref ref;
  48.     if ( get_ref_for_path( name, &ref) == B_OK )
  49.         fName.SetTo( ref.name );
  50. }
  51. PlaylistItem::~PlaylistItem()
  52. {
  53. }
  54. /*****************************************************************************
  55.  * PlaylistItem::DrawItem
  56.  *****************************************************************************/
  57. void
  58. PlaylistItem::Draw( BView *owner, BRect frame, bool tintedLine,
  59.                     uint32 mode, bool active, bool playing )
  60. {
  61.     rgb_color color = (rgb_color){ 255, 255, 255, 255 };
  62.     if ( tintedLine )
  63.         color = tint_color( color, 1.04 );
  64.     // background
  65.     if ( IsSelected() )
  66.         color = tint_color( color, B_DARKEN_2_TINT );
  67.     owner->SetLowColor( color );
  68.     owner->FillRect( frame, B_SOLID_LOW );
  69.     // label
  70.     owner->SetHighColor( 0, 0, 0, 255 );
  71.     font_height fh;
  72.     owner->GetFontHeight( &fh );
  73.     const char* text = Text();
  74.     switch ( mode )
  75.     {
  76.         case DISPLAY_NAME:
  77.             if ( fName.CountChars() > 0 )
  78.                 text = fName.String();
  79.             break;
  80.         case DISPLAY_PATH:
  81.         default:
  82.             break;
  83.     }
  84.     BString truncatedString( text );
  85.     owner->TruncateString( &truncatedString, B_TRUNCATE_MIDDLE,
  86.                            frame.Width() - TEXT_OFFSET - 4.0 );
  87.     owner->DrawString( truncatedString.String(),
  88.                        BPoint( frame.left + TEXT_OFFSET,
  89.                                frame.top + fh.ascent + 1.0 ) );
  90.     // playmark
  91.     if ( active )
  92.     {
  93.         rgb_color black = (rgb_color){ 0, 0, 0, 255 };
  94.         rgb_color green = (rgb_color){ 0, 255, 0, 255 };
  95.         BRect r( 0.0, 0.0, 10.0, 10.0 );
  96.         r.OffsetTo( frame.left + 4.0,
  97.                     ceilf( ( frame.top + frame.bottom ) / 2.0 ) - 5.0 );
  98.         if ( !playing )
  99.             green = tint_color( color, B_DARKEN_1_TINT );
  100.         rgb_color lightGreen = tint_color( green, B_LIGHTEN_2_TINT );
  101.         rgb_color darkGreen = tint_color( green, B_DARKEN_2_TINT );
  102.         BPoint arrow[3];
  103.         arrow[0] = r.LeftTop();
  104.         arrow[1] = r.LeftBottom();
  105.         arrow[2].x = r.right;
  106.         arrow[2].y = ( r.top + r.bottom ) / 2.0;
  107.         owner->BeginLineArray( 6 );
  108.             // black outline
  109.             owner->AddLine( arrow[0], arrow[1], black );
  110.             owner->AddLine( BPoint( arrow[1].x + 1.0, arrow[1].y - 1.0 ),
  111.                             arrow[2], black );
  112.             owner->AddLine( arrow[0], arrow[2], black );
  113.             // inset arrow
  114.             arrow[0].x += 1.0;
  115.             arrow[0].y += 2.0;
  116.             arrow[1].x += 1.0;
  117.             arrow[1].y -= 2.0;
  118.             arrow[2].x -= 2.0;
  119.             // highlights and shadow
  120.             owner->AddLine( arrow[1], arrow[2], darkGreen );
  121.             owner->AddLine( arrow[0], arrow[2], lightGreen );
  122.             owner->AddLine( arrow[0], arrow[1], lightGreen );
  123.         owner->EndLineArray();
  124.         // fill green
  125.         arrow[0].x += 1.0;
  126.         arrow[0].y += 1.0;
  127.         arrow[1].x += 1.0;
  128.         arrow[1].y -= 1.0;
  129.         arrow[2].x -= 2.0;
  130.         owner->SetHighColor( green );
  131.         owner->FillPolygon( arrow, 3 );
  132.     }
  133. }
  134. /*****************************************************************************
  135.  * DragSortableListView class
  136.  *****************************************************************************/
  137. DragSortableListView::DragSortableListView( BRect frame, const char* name,
  138.                                             list_view_type type, uint32 resizingMode,
  139.                                             uint32 flags )
  140.     : BListView( frame, name, type, resizingMode, flags ),
  141.       fDropRect( 0.0, 0.0, -1.0, -1.0 ),
  142.       fDropIndex( -1 )
  143. {
  144.     SetViewColor( B_TRANSPARENT_32_BIT );
  145. }
  146. DragSortableListView::~DragSortableListView()
  147. {
  148. }
  149. /*****************************************************************************
  150.  * DragSortableListView::Draw
  151.  *****************************************************************************/
  152. void
  153. DragSortableListView::Draw( BRect updateRect )
  154. {
  155.     int32 firstIndex = IndexOf( updateRect.LeftTop() );
  156.     int32 lastIndex = IndexOf( updateRect.RightBottom() );
  157.     if ( firstIndex >= 0 )
  158.     {
  159.         if ( lastIndex < firstIndex )
  160.             lastIndex = CountItems() - 1;
  161.         // update rect contains items
  162.         BRect r( updateRect );
  163.         for ( int32 i = firstIndex; i <= lastIndex; i++)
  164.         {
  165.             r = ItemFrame( i );
  166.             DrawListItem( this, i, r );
  167.         }
  168.         updateRect.top = r.bottom + 1.0;
  169.         if ( updateRect.IsValid() )
  170.         {
  171.             SetLowColor( 255, 255, 255, 255 );
  172.             FillRect( updateRect, B_SOLID_LOW );
  173.         }
  174.     }
  175.     else
  176.     {
  177.         SetLowColor( 255, 255, 255, 255 );
  178.         FillRect( updateRect, B_SOLID_LOW );
  179.     }
  180.     // drop anticipation indication
  181.     if ( fDropRect.IsValid() )
  182.     {
  183.         SetHighColor( 255, 0, 0, 255 );
  184.         StrokeRect( fDropRect );
  185.     }
  186. }
  187. /*****************************************************************************
  188.  * DragSortableListView::InitiateDrag
  189.  *****************************************************************************/
  190. bool
  191. DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
  192. {
  193.     bool success = false;
  194.     BListItem* item = ItemAt( CurrentSelection( 0 ) );
  195.     if ( !item )
  196.     {
  197.         // workarround a timing problem
  198.         Select( index );
  199.         item = ItemAt( index );
  200.     }
  201.     if ( item )
  202.     {
  203.         // create drag message
  204.         BMessage msg( B_SIMPLE_DATA );
  205.         MakeDragMessage( &msg );
  206.         // figure out drag rect
  207.         float width = Bounds().Width();
  208.         BRect dragRect(0.0, 0.0, width, -1.0);
  209.         // figure out, how many items fit into our bitmap
  210.         int32 numItems;
  211.         bool fade = false;
  212.         for (numItems = 0; BListItem* item = ItemAt( CurrentSelection( numItems ) ); numItems++) {
  213.             dragRect.bottom += ceilf( item->Height() ) + 1.0;
  214.             if ( dragRect.Height() > MAX_DRAG_HEIGHT ) {
  215.                 fade = true;
  216.                 dragRect.bottom = MAX_DRAG_HEIGHT;
  217.                 numItems++;
  218.                 break;
  219.             }
  220.         }
  221.         BBitmap* dragBitmap = new BBitmap( dragRect, B_RGB32, true );
  222.         if ( dragBitmap && dragBitmap->IsValid() ) {
  223.             if ( BView *v = new BView( dragBitmap->Bounds(), "helper", B_FOLLOW_NONE, B_WILL_DRAW ) ) {
  224.                 dragBitmap->AddChild( v );
  225.                 dragBitmap->Lock();
  226.                 BRect itemBounds( dragRect) ;
  227.                 itemBounds.bottom = 0.0;
  228.                 // let all selected items, that fit into our drag_bitmap, draw
  229.                 for ( int32 i = 0; i < numItems; i++ ) {
  230.                     int32 index = CurrentSelection( i );
  231.                     BListItem* item = ItemAt( index );
  232.                     itemBounds.bottom = itemBounds.top + ceilf( item->Height() );
  233.                     if ( itemBounds.bottom > dragRect.bottom )
  234.                         itemBounds.bottom = dragRect.bottom;
  235.                     DrawListItem( v, index, itemBounds );
  236.                     itemBounds.top = itemBounds.bottom + 1.0;
  237.                 }
  238.                 // make a black frame arround the edge
  239.                 v->SetHighColor( 0, 0, 0, 255 );
  240.                 v->StrokeRect( v->Bounds() );
  241.                 v->Sync();
  242.  
  243.                 uint8 *bits = (uint8 *)dragBitmap->Bits();
  244.                 int32 height = (int32)dragBitmap->Bounds().Height() + 1;
  245.                 int32 width = (int32)dragBitmap->Bounds().Width() + 1;
  246.                 int32 bpr = dragBitmap->BytesPerRow();
  247.  
  248.                 if (fade) {
  249.                     for ( int32 y = 0; y < height - ALPHA / 2; y++, bits += bpr ) {
  250.                         uint8 *line = bits + 3;
  251.                         for (uint8 *end = line + 4 * width; line < end; line += 4)
  252.                             *line = ALPHA;
  253.                     }
  254.                     for ( int32 y = height - ALPHA / 2; y < height; y++, bits += bpr ) {
  255.                         uint8 *line = bits + 3;
  256.                         for (uint8 *end = line + 4 * width; line < end; line += 4)
  257.                             *line = (height - y) << 1;
  258.                     }
  259.                 } else {
  260.                     for ( int32 y = 0; y < height; y++, bits += bpr ) {
  261.                         uint8 *line = bits + 3;
  262.                         for (uint8 *end = line + 4 * width; line < end; line += 4)
  263.                             *line = ALPHA;
  264.                     }
  265.                 }
  266.                 dragBitmap->Unlock();
  267.                 success = true;
  268.             }
  269.         }
  270.         if (success)
  271.             DragMessage( &msg, dragBitmap, B_OP_ALPHA, BPoint( 0.0, 0.0 ) );
  272.         else {
  273.             delete dragBitmap;
  274.             DragMessage( &msg, dragRect.OffsetToCopy( point ), this );
  275.         }
  276.     }
  277.     return success;
  278. }
  279. /*****************************************************************************
  280.  * DragSortableListView::WindowActivated
  281.  *****************************************************************************/
  282. void
  283. DragSortableListView::WindowActivated( bool active )
  284. {
  285.     // workarround for buggy focus indication of BScrollView
  286.     if ( BView* view = Parent() )
  287.         view->Invalidate();
  288. }
  289. /*****************************************************************************
  290.  * DragSortableListView::MessageReceived
  291.  *****************************************************************************/
  292. void
  293. DragSortableListView::MessageReceived(BMessage* message)
  294. {
  295.     switch ( message->what )
  296.     {
  297.         case B_MODIFIERS_CHANGED:
  298.             ModifiersChanged();
  299.             break;
  300.         case B_SIMPLE_DATA:
  301.         {
  302.             DragSortableListView *list = NULL;
  303.             if ( message->FindPointer( "list", (void **)&list ) == B_OK
  304.                  && list == this )
  305.             {
  306.                 int32 count = CountItems();
  307.                 if ( fDropIndex < 0 || fDropIndex > count )
  308.                     fDropIndex = count;
  309.                 BList items;
  310.                 int32 index;
  311.                 for ( int32 i = 0; message->FindInt32( "index", i, &index ) == B_OK; i++ )
  312.                     if ( BListItem* item = ItemAt(index) )
  313.                         items.AddItem( (void*)item );
  314.                 if ( items.CountItems() > 0 )
  315.                 {
  316.                     if ( modifiers() & B_SHIFT_KEY )
  317.                         CopyItems( items, fDropIndex );
  318.                     else
  319.                         MoveItems( items, fDropIndex );
  320.                 }
  321.                 fDropIndex = -1;
  322.             }
  323.             break;
  324.         }
  325.         default:
  326.             BListView::MessageReceived( message );
  327.             break;
  328.     }
  329. }
  330. /*****************************************************************************
  331.  * DragSortableListView::MouseMoved
  332.  *****************************************************************************/
  333. void
  334. DragSortableListView::MouseMoved(BPoint where, uint32 transit, const BMessage *msg)
  335. {
  336.     if ( msg && ( msg->what == B_SIMPLE_DATA || msg->what == MSG_SOUNDPLAY ) )
  337.     {
  338.         bool replaceAll = !msg->HasPointer("list") && !(modifiers() & B_SHIFT_KEY);
  339.         switch ( transit )
  340.         {
  341.             case B_ENTERED_VIEW:
  342.                 // remember drag message
  343.                 // this is needed to react on modifier changes
  344.                 fDragMessageCopy = *msg;
  345.             case B_INSIDE_VIEW:
  346.             {
  347.                 if ( replaceAll )
  348.                 {
  349.                     BRect r( Bounds() );
  350.                     r.bottom--;    // compensate for scrollbar offset
  351.                     _SetDropAnticipationRect( r );
  352.                     fDropIndex = -1;
  353.                 }
  354.                 else
  355.                 {
  356.                     // offset where by half of item height
  357.                     BRect r( ItemFrame( 0 ) );
  358.                     where.y += r.Height() / 2.0;
  359.  
  360.                     int32 index = IndexOf( where );
  361.                     if ( index < 0 )
  362.                         index = CountItems();
  363.                     _SetDropIndex( index );
  364.                 }
  365.                 break;
  366.             }
  367.             case B_EXITED_VIEW:
  368.                 // forget drag message
  369.                 fDragMessageCopy.what = 0;
  370.             case B_OUTSIDE_VIEW:
  371.                 _RemoveDropAnticipationRect();
  372.                 break;
  373.         }
  374.     }
  375.     else
  376.     {
  377.         _RemoveDropAnticipationRect();
  378.         BListView::MouseMoved(where, transit, msg);
  379.         fDragMessageCopy.what = 0;
  380.     }
  381. }
  382. /*****************************************************************************
  383.  * DragSortableListView::MouseUp
  384.  *****************************************************************************/
  385. void
  386. DragSortableListView::MouseUp( BPoint where )
  387. {
  388.     // remove drop mark
  389.     _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
  390.     // be sure to forget drag message
  391.     fDragMessageCopy.what = 0;
  392.     BListView::MouseUp( where );
  393. }
  394. /*****************************************************************************
  395.  * DragSortableListView::DrawItem
  396.  *****************************************************************************/
  397. void
  398. DragSortableListView::DrawItem( BListItem *item, BRect itemFrame, bool complete )
  399. {
  400.     DrawListItem( this, IndexOf( item ), itemFrame );
  401. }
  402. /*****************************************************************************
  403.  * DragSortableListView::ModifiersChaned
  404.  *****************************************************************************/
  405. void
  406. DragSortableListView::ModifiersChanged()
  407. {
  408.     BPoint where;
  409.     uint32 buttons;
  410.     GetMouse( &where, &buttons, false );
  411.     uint32 transit = Bounds().Contains( where ) ? B_INSIDE_VIEW : B_OUTSIDE_VIEW;
  412.     MouseMoved( where, transit, &fDragMessageCopy );
  413. }
  414. /*****************************************************************************
  415.  * DragSortableListView::MoveItems
  416.  *****************************************************************************/
  417. void
  418. DragSortableListView::MoveItems( BList& items, int32 index )
  419. {
  420.     DeselectAll();
  421.     // we remove the items while we look at them, the insertion index is decreased
  422.     // when the items index is lower, so that we insert at the right spot after
  423.     // removal
  424.     BList removedItems;
  425.     int32 count = items.CountItems();
  426.     for ( int32 i = 0; i < count; i++ )
  427.     {
  428.         BListItem* item = (BListItem*)items.ItemAt( i );
  429.         int32 removeIndex = IndexOf( item );
  430.         if ( RemoveItem( item ) && removedItems.AddItem( (void*)item ) )
  431.         {
  432.             if ( removeIndex < index )
  433.                 index--;
  434.         }
  435.         // else ??? -> blow up
  436.     }
  437.     for ( int32 i = 0; BListItem* item = (BListItem*)removedItems.ItemAt( i ); i++ )
  438.     {
  439.         if ( AddItem( item, index ) )
  440.         {
  441.             // after we're done, the newly inserted items will be selected
  442.             Select( index, true );
  443.             // next items will be inserted after this one
  444.             index++;
  445.         }
  446.         else
  447.             delete item;
  448.     }
  449. }
  450. /*****************************************************************************
  451.  * DragSortableListView::CopyItems
  452.  *****************************************************************************/
  453. void
  454. DragSortableListView::CopyItems( BList& items, int32 index )
  455. {
  456.     DeselectAll();
  457.     // by inserting the items after we copied all items first, we avoid
  458.     // cloning an item we already inserted and messing everything up
  459.     // in other words, don't touch the list before we know which items
  460.     // need to be cloned
  461.     BList clonedItems;
  462.     int32 count = items.CountItems();
  463.     for ( int32 i = 0; i < count; i++ )
  464.     {
  465.         BListItem* item = CloneItem( IndexOf( (BListItem*)items.ItemAt( i ) ) );
  466.         if ( item && !clonedItems.AddItem( (void*)item ) )
  467.             delete item;
  468.     }
  469.     for ( int32 i = 0; BListItem* item = (BListItem*)clonedItems.ItemAt( i ); i++ )
  470.     {
  471.         if ( AddItem( item, index ) )
  472.         {
  473.             // after we're done, the newly inserted items will be selected
  474.             Select( index, true );
  475.             // next items will be inserted after this one
  476.             index++;
  477.         }
  478.         else
  479.             delete item;
  480.     }
  481. }
  482. /*****************************************************************************
  483.  * DragSortableListView::RemoveItemList
  484.  *****************************************************************************/
  485. void
  486. DragSortableListView::RemoveItemList( BList& items )
  487. {
  488.     int32 count = items.CountItems();
  489.     for ( int32 i = 0; i < count; i++ )
  490.     {
  491.         BListItem* item = (BListItem*)items.ItemAt( i );
  492.         if ( RemoveItem( item ) )
  493.             delete item;
  494.     }
  495. }
  496. /*****************************************************************************
  497.  * DragSortableListView::RemoveSelected
  498.  *****************************************************************************/
  499. void
  500. DragSortableListView::RemoveSelected()
  501. {
  502.     BList items;
  503.     for ( int32 i = 0; BListItem* item = ItemAt( CurrentSelection( i ) ); i++ )
  504.         items.AddItem( (void*)item );
  505.     RemoveItemList( items );
  506. }
  507. /*****************************************************************************
  508.  * DragSortableListView::CountSelectedItems
  509.  *****************************************************************************/
  510. int32
  511. DragSortableListView::CountSelectedItems() const
  512. {
  513.     int32 count = 0;
  514.     while ( CurrentSelection( count ) >= 0 )
  515.         count++;
  516.     return count;
  517. }
  518. /*****************************************************************************
  519.  * DragSortableListView::_SetDropAnticipationRect
  520.  *****************************************************************************/
  521. void
  522. DragSortableListView::_SetDropAnticipationRect( BRect r )
  523. {
  524.     if ( fDropRect != r )
  525.     {
  526.         if ( fDropRect.IsValid() )
  527.             Invalidate( fDropRect );
  528.         fDropRect = r;
  529.         if ( fDropRect.IsValid() )
  530.             Invalidate( fDropRect );
  531.     }
  532. }
  533. /*****************************************************************************
  534.  * DragSortableListView::_SetDropAnticipationRect
  535.  *****************************************************************************/
  536. void
  537. DragSortableListView::_SetDropIndex( int32 index )
  538. {
  539.     if ( fDropIndex != index )
  540.     {
  541.         fDropIndex = index;
  542.         if ( fDropIndex == -1 )
  543.             _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
  544.         else
  545.         {
  546.             int32 count = CountItems();
  547.             if ( fDropIndex == count )
  548.             {
  549.                 BRect r;
  550.                 if ( BListItem* item = ItemAt( count - 1 ) )
  551.                 {
  552.                     r = ItemFrame( count - 1 );
  553.                     r.top = r.bottom + 1.0;
  554.                     r.bottom = r.top + 1.0;
  555.                 }
  556.                 else
  557.                 {
  558.                     r = Bounds();
  559.                     r.bottom--;    // compensate for scrollbars moved slightly out of window
  560.                 }
  561.                 _SetDropAnticipationRect( r );
  562.             }
  563.             else
  564.             {
  565.                 BRect r = ItemFrame( fDropIndex );
  566.                 r.bottom = r.top + 1.0;
  567.                 _SetDropAnticipationRect( r );
  568.             }
  569.         }
  570.     }
  571. }
  572. /*****************************************************************************
  573.  * DragSortableListView::_RemoveDropAnticipationRect
  574.  *****************************************************************************/
  575. void
  576. DragSortableListView::_RemoveDropAnticipationRect()
  577. {
  578.     _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
  579.     _SetDropIndex( -1 );
  580. }
  581. /*****************************************************************************
  582.  * PlaylistView class
  583.  *****************************************************************************/
  584. PlaylistView::PlaylistView( intf_thread_t * _p_intf,
  585.                             BRect frame, InterfaceWindow* mainWindow,
  586.                             BMessage* selectionChangeMessage )
  587.     : DragSortableListView( frame, "playlist listview",
  588.                             B_MULTIPLE_SELECTION_LIST, B_FOLLOW_ALL_SIDES,
  589.                             B_WILL_DRAW | B_NAVIGABLE | B_PULSE_NEEDED
  590.                             | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE ),
  591.       p_intf( _p_intf ),
  592.       fCurrentIndex( -1 ),
  593.       fPlaying( false ),
  594.       fDisplayMode( DISPLAY_PATH ),
  595.       fMainWindow( mainWindow ),
  596.       fSelectionChangeMessage( selectionChangeMessage ),
  597.       fLastClickedItem( NULL )
  598. {
  599. }
  600. PlaylistView::~PlaylistView()
  601. {
  602.     delete fSelectionChangeMessage;
  603. }
  604. /*****************************************************************************
  605.  * PlaylistView::AttachedToWindow
  606.  *****************************************************************************/
  607. void
  608. PlaylistView::AttachedToWindow()
  609. {
  610.     // get pulse message every two frames
  611.     Window()->SetPulseRate( 80000 );
  612. }
  613. /*****************************************************************************
  614.  * PlaylistView::MessageReceived
  615.  *****************************************************************************/
  616. void
  617. PlaylistView::MessageReceived( BMessage* message)
  618. {
  619.     switch ( message->what )
  620.     {
  621.         case MSG_SOUNDPLAY:
  622.         case B_SIMPLE_DATA:
  623.             if ( message->HasPointer( "list" ) )
  624.             {
  625.                 // message comes from ourself
  626.                 DragSortableListView::MessageReceived( message );
  627.             }
  628.             else
  629.             {
  630.                 // message comes from another app (for example Tracker)
  631.                 message->AddInt32( "drop index", fDropIndex );
  632.                 fMainWindow->PostMessage( message, fMainWindow );
  633.             }
  634.             break;
  635.         default:
  636.             DragSortableListView::MessageReceived( message );
  637.             break;
  638.     }
  639. }
  640. /*****************************************************************************
  641.  * PlaylistView::MouseDown
  642.  *****************************************************************************/
  643. void
  644. PlaylistView::MouseDown( BPoint where )
  645. {
  646.     int32 clicks = 1;
  647.     Window()->CurrentMessage()->FindInt32( "clicks", &clicks );
  648.     bool handled = false;
  649.     for ( int32 i = 0; PlaylistItem* item = (PlaylistItem*)ItemAt( i ); i++ )
  650.     {
  651.         BRect r = ItemFrame( i );
  652.         if ( r.Contains( where ) )
  653.         {
  654.             if ( clicks == 2 )
  655.             {
  656.                 // only do something if user clicked the same item twice
  657.                 if ( fLastClickedItem == item )
  658.                 {
  659.                     playlist_t * p_playlist = pl_Hold( p_intf );
  660.                     if( p_playlist )
  661.                     {
  662.                         playlist_Goto( p_playlist, i );
  663.                         pl_Release( p_intf );
  664.                     }
  665.                     handled = true;
  666.                 }
  667.             }
  668.             else
  669.             {
  670.                 // remember last clicked item
  671.                 fLastClickedItem = item;
  672.                 if ( i == fCurrentIndex )
  673.                 {
  674.                     r.right = r.left + TEXT_OFFSET;
  675.                     if ( r.Contains ( where ) )
  676.                     {
  677.                         fMainWindow->PostMessage( PAUSE_PLAYBACK );
  678.                         InvalidateItem( i );
  679.                         handled = true;
  680.                     }
  681.                 }
  682.             }
  683.             break;
  684.         }
  685.     }
  686.     if ( !handled )
  687.         DragSortableListView::MouseDown(where);
  688. }
  689. /*****************************************************************************
  690.  * PlaylistView::KeyDown
  691.  *****************************************************************************/
  692. void
  693. PlaylistView::KeyDown( const char* bytes, int32 numBytes )
  694. {
  695.     if ( numBytes < 1 )
  696.         return;
  697.  
  698.     if ( ( bytes[0] == B_BACKSPACE ) || ( bytes[0] == B_DELETE ) )
  699.     {
  700.         RemoveSelected();
  701.     }
  702.     DragSortableListView::KeyDown( bytes, numBytes );
  703. }
  704. /*****************************************************************************
  705.  * PlaylistView::Pulse
  706.  *****************************************************************************/
  707. void
  708. PlaylistView::Pulse()
  709. {
  710.     if ( fMainWindow->IsStopped() )
  711.         SetPlaying( false );
  712. }
  713. /*****************************************************************************
  714.  * PlaylistView::SelectionChanged
  715.  *****************************************************************************/
  716. void
  717. PlaylistView::SelectionChanged()
  718. {
  719.     BLooper* looper = Looper();
  720.     if ( fSelectionChangeMessage && looper )
  721.     {
  722.         BMessage message( *fSelectionChangeMessage );
  723.         looper->PostMessage( &message );
  724.     }
  725. }
  726. /*****************************************************************************
  727.  * PlaylistView::MoveItems
  728.  *****************************************************************************/
  729. void
  730. PlaylistView::MoveItems( BList& items, int32 index )
  731. {
  732. #if 0
  733.     DeselectAll();
  734.     // we remove the items while we look at them, the insertion index is decreased
  735.     // when the items index is lower, so that we insert at the right spot after
  736.     // removal
  737.     if ( fVlcWrapper->PlaylistLock() )
  738.     {
  739.         BList removedItems;
  740.         BList removeItems;
  741.         int32 count = items.CountItems();
  742.         int32 indexOriginal = index;
  743.         // remember currently playing item
  744.         BListItem* playingItem = _PlayingItem();
  745.         // collect item pointers for removal by index
  746.         for ( int32 i = 0; i < count; i++ )
  747.         {
  748.             int32 removeIndex = IndexOf( (BListItem*)items.ItemAt( i ) );
  749.             void* item = fVlcWrapper->PlaylistItemAt( removeIndex );
  750.             if ( item && removeItems.AddItem( item ) )
  751.             {
  752.                 if ( removeIndex < index )
  753.                     index--;
  754.             }
  755.             // else ??? -> blow up
  756.         }
  757.         // actually remove items using pointers
  758.         for ( int32 i = 0; i < count; i++ )
  759.         {
  760.             void* item = fVlcWrapper->PlaylistRemoveItem( removeItems.ItemAt( i ) );
  761.             if ( item && !removedItems.AddItem( item ) )
  762.                 free( item );
  763.         }
  764.         // add items at index
  765.         for ( int32 i = 0; void* item = removedItems.ItemAt( i ); i++ )
  766.         {
  767.             if ( fVlcWrapper->PlaylistAddItem( item, index ) )
  768.                 // next items will be inserted after this one
  769.                 index++;
  770.             else
  771.                 free( item );
  772.         }
  773.         // update GUI
  774.         DragSortableListView::MoveItems( items, indexOriginal );
  775.         // restore currently playing item
  776.         _SetPlayingIndex( playingItem );
  777.         // update interface (in case it isn't playing,
  778.         // there is a chance that it needs to update)
  779.         fMainWindow->PostMessage( MSG_UPDATE );
  780.         fVlcWrapper->PlaylistUnlock();
  781.     }
  782. #endif
  783. }
  784. /*****************************************************************************
  785.  * PlaylistView::CopyItems
  786.  *****************************************************************************/
  787. void
  788. PlaylistView::CopyItems( BList& items, int32 toIndex )
  789. {
  790. #if 0
  791.     DeselectAll();
  792.     // we remove the items while we look at them, the insertion index is decreased
  793.     // when the items index is lower, so that we insert at the right spot after
  794.     // removal
  795.     if ( fVlcWrapper->PlaylistLock() )
  796.     {
  797.         BList clonedItems;
  798.         int32 count = items.CountItems();
  799.         // remember currently playing item
  800.         BListItem* playingItem = _PlayingItem();
  801.         // collect cloned item pointers
  802.         for ( int32 i = 0; i < count; i++ )
  803.         {
  804.             int32 index = IndexOf( (BListItem*)items.ItemAt( i ) );
  805.             void* item = fVlcWrapper->PlaylistItemAt( index );
  806.             void* cloned = fVlcWrapper->PlaylistCloneItem( item );
  807.             if ( cloned && !clonedItems.AddItem( cloned ) )
  808.                 free( cloned );
  809.  
  810.         }
  811.         // add cloned items at index
  812.         int32 index = toIndex;
  813.         for ( int32 i = 0; void* item = clonedItems.ItemAt( i ); i++ )
  814.         {
  815.             if ( fVlcWrapper->PlaylistAddItem( item, index ) )
  816.                 // next items will be inserted after this one
  817.                 index++;
  818.             else
  819.                 free( item );
  820.         }
  821.         // update GUI
  822.         DragSortableListView::CopyItems( items, toIndex );
  823.         // restore currently playing item
  824.         _SetPlayingIndex( playingItem );
  825.         // update interface (in case it isn't playing,
  826.         // there is a chance that it needs to update)
  827.         fMainWindow->PostMessage( MSG_UPDATE );
  828.         fVlcWrapper->PlaylistUnlock();
  829.     }
  830. #endif
  831. }
  832. /*****************************************************************************
  833.  * PlaylistView::RemoveItemList
  834.  *****************************************************************************/
  835. void
  836. PlaylistView::RemoveItemList( BList& items )
  837. {
  838. #if 0
  839.     if ( fVlcWrapper->PlaylistLock() )
  840.     {
  841.         // remember currently playing item
  842.         BListItem* playingItem = _PlayingItem();
  843.         // collect item pointers for removal
  844.         BList removeItems;
  845.         int32 count = items.CountItems();
  846.         for ( int32 i = 0; i < count; i++ )
  847.         {
  848.             int32 index = IndexOf( (BListItem*)items.ItemAt( i ) );
  849.             void* item = fVlcWrapper->PlaylistItemAt( index );
  850.             if ( item && !removeItems.AddItem( item ) )
  851.                 free( item );
  852.         }
  853.         // remove items from playlist
  854.         count = removeItems.CountItems();
  855.         for ( int32 i = 0; void* item = removeItems.ItemAt( i ); i++ )
  856.         {
  857.             fVlcWrapper->PlaylistRemoveItem( item );
  858.         }
  859.         // update GUI
  860.         DragSortableListView::RemoveItemList( items );
  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();
  867.     }
  868. #endif
  869. }
  870. /*****************************************************************************
  871.  * PlaylistView::CloneItem
  872.  *****************************************************************************/
  873. BListItem*
  874. PlaylistView::CloneItem( int32 atIndex ) const
  875. {
  876.     BListItem* clone = NULL;
  877.     if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( atIndex ) ) )
  878.         clone = new PlaylistItem( item->Text() );
  879.     return clone;
  880. }
  881. /*****************************************************************************
  882.  * PlaylistView::DrawListItem
  883.  *****************************************************************************/
  884. void
  885. PlaylistView::DrawListItem( BView* owner, int32 index, BRect frame ) const
  886. {
  887.     if ( PlaylistItem* item = dynamic_cast<PlaylistItem*>( ItemAt( index ) ) )
  888.         item->Draw( owner,  frame, index % 2,
  889.                     fDisplayMode, index == fCurrentIndex, fPlaying );
  890. }
  891. /*****************************************************************************
  892.  * PlaylistView::MakeDragMessage
  893.  *****************************************************************************/
  894. void
  895. PlaylistView::MakeDragMessage( BMessage* message ) const
  896. {
  897.     if ( message )
  898.     {
  899.         message->AddPointer( "list", (void*)this );
  900.         int32 index;
  901.         for ( int32 i = 0; ( index = CurrentSelection( i ) ) >= 0; i++ )
  902.         {
  903.             message->AddInt32( "index", index );
  904.             // add refs to message (inter application communication)
  905.             if ( BStringItem* item = dynamic_cast<BStringItem*>( ItemAt( index ) ) )
  906.             {
  907.                 entry_ref ref;
  908.                 if ( get_ref_for_path( item->Text(), &ref ) == B_OK )
  909.                     message->AddRef( "refs", &ref );
  910.             }
  911.         }
  912.     }
  913. }
  914. /*****************************************************************************
  915.  * PlaylistView::SetCurrent
  916.  *****************************************************************************/
  917. void
  918. PlaylistView::SetCurrent( int32 index )
  919. {
  920.     if ( fCurrentIndex != index )
  921.     {
  922.         InvalidateItem( fCurrentIndex );
  923.         fCurrentIndex = index;
  924.         InvalidateItem( fCurrentIndex );
  925.     }
  926. }
  927. /*****************************************************************************
  928.  * PlaylistView::SetPlaying
  929.  *****************************************************************************/
  930. void
  931. PlaylistView::SetPlaying( bool playing )
  932. {
  933.     if ( fPlaying != playing )
  934.     {
  935.         fPlaying = playing;
  936.         InvalidateItem( fCurrentIndex );
  937.     }
  938. }
  939. /*****************************************************************************
  940.  * PlaylistView::SetPlaying
  941.  *****************************************************************************/
  942. void
  943. PlaylistView::RebuildList()
  944. {
  945.     playlist_t * p_playlist = pl_Hold( p_intf );
  946.     // remove all items
  947.     BListItem * item;
  948.     int32 count = CountItems();
  949.     while( ( item = RemoveItem( --count ) ) )
  950.         delete item;
  951.     // rebuild listview from VLC's playlist
  952.     PL_LOCK;
  953.     FOREACH_ARRAY( playlist_item_t *p_item, p_playlist->items )
  954.         AddItem( new PlaylistItem( p_item->p_input->psz_name ) );
  955.     FOREACH_END();
  956.     PL_UNLOCK;
  957.     vlc_object_release( p_playlist );
  958. }
  959. /*****************************************************************************
  960.  * PlaylistView::SortReverse
  961.  *****************************************************************************/
  962. void
  963. PlaylistView::SortReverse()
  964. {
  965. #if 0
  966.     if ( int32 count = CountSelectedItems() )
  967.     {
  968.         int32 last  = count - 1;
  969.         // remember currently playing item
  970.         BListItem* playingItem = _PlayingItem();
  971.         for ( int32 first = 0; first < count / 2; first++, last-- )
  972.         {
  973.             int32 index1 = CurrentSelection( first);
  974.             int32 index2 = CurrentSelection( last);
  975.             if ( SwapItems( index1, index2 ) )
  976.             {
  977.                 // index2 > index1, so the list won't get messed up
  978.                 // if we remove the items in that order
  979.                 // TODO: Error checking + handling!
  980.                 void* item2 = fVlcWrapper->PlaylistRemoveItem( index2 );
  981.                 void* item1 = fVlcWrapper->PlaylistRemoveItem( index1 );
  982.                 fVlcWrapper->PlaylistAddItem( item2, index1 );
  983.                 fVlcWrapper->PlaylistAddItem( item1, index2 );
  984.             }
  985.         }
  986.         // restore currently playing item
  987.         _SetPlayingIndex( playingItem );
  988.     }
  989. #endif
  990. }
  991. /*****************************************************************************
  992.  * PlaylistView::SortByPath
  993.  *****************************************************************************/
  994. void
  995. PlaylistView::SortByPath()
  996. {
  997.  
  998. }
  999. /*****************************************************************************
  1000.  * PlaylistView::SortByName
  1001.  *****************************************************************************/
  1002. void
  1003. PlaylistView::SortByName()
  1004. {
  1005. }
  1006. /*****************************************************************************
  1007.  * PlaylistView::SetDisplayMode
  1008.  *****************************************************************************/
  1009. void
  1010. PlaylistView::SetDisplayMode( uint32 mode )
  1011. {
  1012.     if ( mode != fDisplayMode )
  1013.     {
  1014.         fDisplayMode = mode;
  1015.         Invalidate();
  1016.     }
  1017. }
  1018. /*****************************************************************************
  1019.  * PlaylistView::_PlayingItem
  1020.  *****************************************************************************/
  1021. BListItem*
  1022. PlaylistView::_PlayingItem() const
  1023. {
  1024.     playlist_t * p_playlist = pl_Hold( p_intf );
  1025.     if( !p_playlist )
  1026.     {
  1027.         return NULL;
  1028.     }
  1029.     BListItem * item = ItemAt( p_playlist->i_index );
  1030.     pl_Release( p_intf );
  1031.     return item;
  1032. }
  1033. /*****************************************************************************
  1034.  * PlaylistView::_SetPlayingIndex
  1035.  *****************************************************************************/
  1036. void
  1037. PlaylistView::_SetPlayingIndex( BListItem* playingItem )
  1038. {
  1039.     for ( int32 i = 0; BListItem* item = ItemAt( i ); i++ )
  1040.     {
  1041.         if ( item == playingItem )
  1042.         {
  1043.             playlist_t * p_playlist = pl_Hold( p_intf );
  1044.  
  1045.             if( !p_playlist )
  1046.             {
  1047.                 return;
  1048.             }
  1049.             playlist_Goto( p_playlist, i );
  1050.             SetCurrent( i );
  1051.             pl_Release( p_intf );
  1052.             break;
  1053.         }
  1054.     }
  1055. }
  1056. #endif