Changes done since Feb 28 2003:
authorStephan Assmus <stippi@videolan.org>
Sat, 1 Feb 2003 12:01:11 +0000 (12:01 +0000)
committerStephan Assmus <stippi@videolan.org>
Sat, 1 Feb 2003 12:01:11 +0000 (12:01 +0000)
13 files changed:
modules/gui/beos/Interface.cpp
modules/gui/beos/InterfaceWindow.cpp
modules/gui/beos/InterfaceWindow.h
modules/gui/beos/ListViews.cpp
modules/gui/beos/ListViews.h
modules/gui/beos/MediaControlView.cpp
modules/gui/beos/MessagesWindow.cpp
modules/gui/beos/PlayListWindow.cpp
modules/gui/beos/PlayListWindow.h
modules/gui/beos/VideoOutput.cpp
modules/gui/beos/VideoWindow.h
modules/gui/beos/VlcWrapper.cpp
modules/gui/beos/VlcWrapper.h

index 413d49e..f15d51d 100644 (file)
@@ -2,7 +2,7 @@
  * intf_beos.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: Interface.cpp,v 1.8 2003/01/25 20:15:41 titer Exp $
+ * $Id: Interface.cpp,v 1.9 2003/02/01 12:01:10 stippi Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
@@ -70,14 +70,12 @@ int E_(OpenIntf) ( vlc_object_t *p_this )
     p_intf->pf_run = Run;
 
     /* Create the interface window */
-    BScreen *screen;
-    screen = new BScreen();
-    BRect rect = screen->Frame();
+    BScreen screen(B_MAIN_SCREEN_ID);
+    BRect rect = screen.Frame();
     rect.top = rect.bottom-100;
     rect.bottom -= 50;
     rect.left += 50;
     rect.right = rect.left + 350;
-    delete screen;
     p_intf->p_sys->p_window =
         new InterfaceWindow( rect,
                              VOUT_TITLE " (BeOS interface)", p_intf );
index c6c8a19..b42eab2 100644 (file)
@@ -2,7 +2,7 @@
  * InterfaceWindow.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: InterfaceWindow.cpp,v 1.25 2003/01/31 06:45:00 titer Exp $
+ * $Id: InterfaceWindow.cpp,v 1.26 2003/02/01 12:01:10 stippi Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
 #include "InterfaceWindow.h"
 
 #define INTERFACE_UPDATE_TIMEOUT 80000 // 2 frames if at 25 fps
+#define INTERFACE_LOCKING_TIMEOUT 5000
+
+// make_sure_frame_is_on_screen
+bool
+make_sure_frame_is_on_screen( BRect& frame )
+{
+       BScreen screen( B_MAIN_SCREEN_ID );
+       if (frame.IsValid() && screen.IsValid()) {
+               if (!screen.Frame().Contains(frame)) {
+                       // make sure frame fits in the screen
+                       if (frame.Width() > screen.Frame().Width())
+                               frame.right -= frame.Width() - screen.Frame().Width() + 10.0;
+                       if (frame.Height() > screen.Frame().Height())
+                               frame.bottom -= frame.Height() - screen.Frame().Height() + 30.0;
+                       // frame is now at the most the size of the screen
+                       if (frame.right > screen.Frame().right)
+                               frame.OffsetBy(-(frame.right - screen.Frame().right), 0.0);
+                       if (frame.bottom > screen.Frame().bottom)
+                               frame.OffsetBy(0.0, -(frame.bottom - screen.Frame().bottom));
+                       if (frame.left < screen.Frame().left)
+                               frame.OffsetBy((screen.Frame().left - frame.left), 0.0);
+                       if (frame.top < screen.Frame().top)
+                               frame.OffsetBy(0.0, (screen.Frame().top - frame.top));
+               }
+               return true;
+       }
+       return false;
+}
+
+// make_sure_frame_is_within_limits
+void
+make_sure_frame_is_within_limits( BRect& frame, float minWidth, float minHeight,
+                                  float maxWidth, float maxHeight )
+{
+    if ( frame.Width() < minWidth )
+        frame.right = frame.left + minWidth;
+    if ( frame.Height() < minHeight )
+        frame.bottom = frame.top + minHeight;
+    if ( frame.Width() > maxWidth )
+        frame.right = frame.left + maxWidth;
+    if ( frame.Height() > maxHeight )
+        frame.bottom = frame.top + maxHeight;
+}
+
+// get_volume_info
+bool
+get_volume_info( BVolume& volume, BString& volumeName, bool& isCDROM, BString& deviceName )
+{
+       bool success = false;
+       isCDROM = false;
+       deviceName = "";
+       volumeName = "";
+       char name[B_FILE_NAME_LENGTH];
+       if ( volume.GetName( name ) >= B_OK )   // disk is currently mounted
+       {
+               volumeName = name;
+               dev_t dev = volume.Device();
+               fs_info info;
+               if ( fs_stat_dev( dev, &info ) == B_OK )
+               {
+                       success = true;
+                       deviceName = info.device_name;
+                       if ( volume.IsReadOnly() )
+                       {
+                               int i_dev = open( info.device_name, O_RDONLY );
+                               if ( i_dev >= 0 )
+                               {
+                                       device_geometry g;
+                                       if ( ioctl( i_dev, B_GET_GEOMETRY, &g, sizeof( g ) ) >= 0 )
+                                               isCDROM = ( g.device_type == B_CD );
+                                       close( i_dev );
+                               }
+                       }
+               }
+       }
+       return success;
+}
 
 
 /*****************************************************************************
  * InterfaceWindow
  *****************************************************************************/
 
-InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
-                                  intf_thread_t  *p_interface )
+InterfaceWindow::InterfaceWindow( BRect frame, const charname,
+                                  intf_thread_tp_interface )
     : BWindow( frame, name, B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
                B_NOT_ZOOMABLE | B_WILL_ACCEPT_FIRST_CLICK | B_ASYNCHRONOUS_CONTROLS ),
       p_intf( p_interface ),
       fFilePanel( NULL ),
-      fSubtitlesPanel( NULL ),
-      fLastUpdateTime( system_time() )
+      fLastUpdateTime( system_time() ),
+         fSettings( new BMessage( 'sett' ) ),
+         p_wrapper( p_intf->p_sys->p_wrapper )
 {
-    p_intf = p_interface;
-    p_wrapper = p_intf->p_sys->p_wrapper;
+       // TODO: ?!? what about user settings?
     p_intf->p_sys->b_dvdmenus = false;
     
     fPlaylistIsEmpty = !( p_wrapper->PlaylistSize() > 0 );
     
-    BScreen *p_screen = new BScreen();
-    BRect screen_rect = p_screen->Frame();
-    delete p_screen;
+    BScreen screen;
+    BRect screen_rect = screen.Frame();
     BRect window_rect;
     window_rect.Set( ( screen_rect.right - PREFS_WINDOW_WIDTH ) / 2,
                      ( screen_rect.bottom - PREFS_WINDOW_HEIGHT ) / 2,
@@ -129,7 +205,7 @@ InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
     
     fileMenu->AddItem( new CDMenu( "Open Disc" ) );
 
-    fileMenu->AddItem( new BMenuItem( "Load a subtitle file" B_UTF8_ELLIPSIS,
+    fileMenu->AddItem( new BMenuItem( "Open Subtitles" B_UTF8_ELLIPSIS,
                                       new BMessage( LOAD_SUBFILE ) ) );
     
     fileMenu->AddSeparatorItem();
@@ -176,7 +252,7 @@ InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
     fMenuBar->AddItem( fSpeedMenu );
 
     /* Add the Show menu */
-    fShowMenu = new BMenu( "Show" );
+    fShowMenu = new BMenu( "Window" );
     fShowMenu->AddItem( new BMenuItem( "Play List" B_UTF8_ELLIPSIS,
                                        new BMessage( OPEN_PLAYLIST ), 'P') );
     fShowMenu->AddItem( new BMenuItem( "Messages" B_UTF8_ELLIPSIS,
@@ -188,56 +264,106 @@ InterfaceWindow::InterfaceWindow( BRect frame, const char *name,
     /* Prepare fow showing */
     _SetMenusEnabled( false );
     p_mediaControl->SetEnabled( false );
+
+       _RestoreSettings();
     
-    /* Restore interface settings */
+/*    // Restore interface settings
+       // main window size and position
     int i_width = config_GetInt( p_intf, "beos-intf-width" ),
         i_height = config_GetInt( p_intf, "beos-intf-height" ),
         i_xpos = config_GetInt( p_intf, "beos-intf-xpos" ),
         i_ypos = config_GetInt( p_intf, "beos-intf-ypos" );
-    if( i_width && i_height && i_xpos && i_ypos )
+    if( i_width > 20 && i_height > 20 && i_xpos >= 0 && i_ypos >= 0 )
     {
-        /* main window size and position */
-        ResizeTo( i_width, i_height );
-        MoveTo( i_xpos, i_ypos );
+       BRect r( i_xpos, i_ypos, i_xpos + i_width, i_ypos + i_height );
+
+               float minWidth, maxWidth, minHeight, maxHeight;
+               GetSizeLimits( &minWidth, &maxWidth, &minHeight, &maxHeight );
+
+               make_sure_frame_is_within_limits( r, minWidth, minHeight, maxWidth, maxHeight );
+               if ( make_sure_frame_is_on_screen( r ) )
+               {
+               ResizeTo( r.Width(), r.Height() );
+               MoveTo( r.LeftTop() );
+               }
     }
+       // playlist window size and position
     i_width = config_GetInt( p_intf, "beos-playlist-width" ),
     i_height = config_GetInt( p_intf, "beos-playlist-height" ),
     i_xpos = config_GetInt( p_intf, "beos-playlist-xpos" ),
     i_ypos = config_GetInt( p_intf, "beos-playlist-ypos" );
-    if( i_width && i_height && i_xpos && i_ypos )
+    if( i_width > 20 && i_height > 20 && i_xpos >= 0 && i_ypos >= 0 )
     {
-        /* playlist window size and position */
-        fPlaylistWindow->ResizeTo( i_width, i_height );
-        fPlaylistWindow->MoveTo( i_xpos, i_ypos );
+       BRect r( i_xpos, i_ypos, i_xpos + i_width, i_ypos + i_height );
+
+               float minWidth, maxWidth, minHeight, maxHeight;
+               fPlaylistWindow->GetSizeLimits( &minWidth, &maxWidth, &minHeight, &maxHeight );
+
+               make_sure_frame_is_within_limits( r, minWidth, minHeight, maxWidth, maxHeight );
+               if ( make_sure_frame_is_on_screen( r ) )
+               {
+               fPlaylistWindow->ResizeTo( r.Width(), r.Height() );
+               fPlaylistWindow->MoveTo( r.LeftTop() );
+               }
     }
+    // child windows are not running yet, that's why we aint locking them
+    // playlist showing
+    // messages window size and position
     i_width = config_GetInt( p_intf, "beos-messages-width" ),
     i_height = config_GetInt( p_intf, "beos-messages-height" ),
     i_xpos = config_GetInt( p_intf, "beos-messages-xpos" ),
     i_ypos = config_GetInt( p_intf, "beos-messages-ypos" );
     if( i_width && i_height && i_xpos && i_ypos )
     {
-        /* messages window size and position */
-        fMessagesWindow->ResizeTo( i_width, i_height );
-        fMessagesWindow->MoveTo( i_xpos, i_ypos );
+       BRect r( i_xpos, i_ypos, i_xpos + i_width, i_ypos + i_height );
+
+               float minWidth, maxWidth, minHeight, maxHeight;
+               fMessagesWindow->GetSizeLimits( &minWidth, &maxWidth, &minHeight, &maxHeight );
+
+               make_sure_frame_is_within_limits( r, minWidth, minHeight, maxWidth, maxHeight );
+               if ( make_sure_frame_is_on_screen( r ) )
+               {
+               fMessagesWindow->ResizeTo( r.Width(), r.Height() );
+               fMessagesWindow->MoveTo( r.LeftTop() );
+               }
     }
     if( config_GetInt( p_intf, "beos-playlist-show" ) )
     {
-        /* playlist showing */
-        if( fPlaylistWindow->Lock() )
-        {
-            fPlaylistWindow->Show();
-            fPlaylistWindow->Unlock();
-        }
+               fPlaylistWindow->Show();
     }
+    else
+    {
+               fPlaylistWindow->Hide();
+               fPlaylistWindow->Show();
+    }
+       // messages window size and position
+    i_width = config_GetInt( p_intf, "beos-messages-width" ),
+    i_height = config_GetInt( p_intf, "beos-messages-height" ),
+    i_xpos = config_GetInt( p_intf, "beos-messages-xpos" ),
+    i_ypos = config_GetInt( p_intf, "beos-messages-ypos" );
+    if( i_width > 20 && i_height > 20 && i_xpos >= 0 && i_ypos >= 0 )
+    {
+       BRect r( i_xpos, i_ypos, i_xpos + i_width, i_ypos + i_height );
+               float minWidth, maxWidth, minHeight, maxHeight;
+               fMessagesWindow->GetSizeLimits( &minWidth, &maxWidth, &minHeight, &maxHeight );
+
+               make_sure_frame_is_within_limits( r, minWidth, minHeight, maxWidth, maxHeight );
+               if ( make_sure_frame_is_on_screen( r ) )
+               {
+               fMessagesWindow->ResizeTo( r.Width(), r.Height() );
+               fMessagesWindow->MoveTo( r.LeftTop() );
+               }
+    }
+    // messages showing
     if( config_GetInt( p_intf, "beos-messages-show" ) )
     {
-        /* messages showing */
-        if( fMessagesWindow->Lock() )
-        {
-            fMessagesWindow->Show();
-            fMessagesWindow->Unlock();
-        }
+               fMessagesWindow->Show();
     }
+    else
+    {
+               fMessagesWindow->Hide();
+               fMessagesWindow->Show();
+    }*/
     
     Show();
 }
@@ -246,8 +372,12 @@ InterfaceWindow::~InterfaceWindow()
 {
     if( fPlaylistWindow )
         fPlaylistWindow->ReallyQuit();
+    fPlaylistWindow = NULL;
     if( fMessagesWindow )
         fMessagesWindow->ReallyQuit();
+    fMessagesWindow = NULL;
+       delete fFilePanel;
+       delete fSettings;
 }
 
 /*****************************************************************************
@@ -285,16 +415,13 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             break;
             
         case OPEN_FILE:
-            if( fFilePanel )
-            {
-                fFilePanel->Show();
-                break;
-            }
-            fFilePanel = new BFilePanel();
-            fFilePanel->SetTarget( this );
-            fFilePanel->Show();
+               _ShowFilePanel( B_REFS_RECEIVED, "VideoLAN Client: Open Media Files" );
             break;
-    
+
+        case LOAD_SUBFILE:
+               _ShowFilePanel( SUBFILE_RECEIVED, "VideoLAN Client: Open Subtitle File" );
+            break;
+
         case OPEN_PLAYLIST:
             if (fPlaylistWindow->Lock())
             {
@@ -318,18 +445,6 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             }
             break;
         
-        case LOAD_SUBFILE:
-            if( fSubtitlesPanel )
-            {
-                fSubtitlesPanel->Show();
-                break;
-            }
-            fSubtitlesPanel = new BFilePanel();
-            fSubtitlesPanel->SetTarget( this );
-            fSubtitlesPanel->SetMessage( new BMessage( SUBFILE_RECEIVED ) );
-            fSubtitlesPanel->Show();
-            break;
-
         case SUBFILE_RECEIVED:
         {
             entry_ref ref;
@@ -337,7 +452,7 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             {
                 BPath path( &ref );
                 if ( path.InitCheck() == B_OK )
-                    p_wrapper->LoadSubFile( (char*)path.Path() );
+                    p_wrapper->LoadSubFile( path.Path() );
             }
             break;
         }
@@ -346,7 +461,6 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
             // this currently stops playback not nicely
             if (playback_status > UNDEF_S)
             {
-                snooze( 400000 );
                 p_wrapper->PlaylistStop();
                 p_mediaControl->SetStatus(NOT_STARTED_S, DEFAULT_RATE);
             }
@@ -512,73 +626,73 @@ void InterfaceWindow::MessageReceived( BMessage * p_message )
                     if ( path.InitCheck() == B_OK )
                     {
                         bool add = true;
-                        // has the user dropped a dvd disk icon?
+                        // has the user dropped a folder?
                         BDirectory dir( &ref );
-                        if ( dir.InitCheck() == B_OK && dir.IsRootDirectory() )
+                        if ( dir.InitCheck() == B_OK)
                         {
-                            BVolumeRoster volRoster;
-                            BVolume vol;
-                            BDirectory volumeRoot;
-                            status_t status = volRoster.GetNextVolume( &vol );
-                            while( status == B_NO_ERROR )
-                            {
-                                if( vol.GetRootDirectory( &volumeRoot ) == B_OK
-                                    && dir == volumeRoot )
-                                {
-                                    BString volumeName;
-                                    BString deviceName;
-                                    bool isCDROM = false;
-                                    bool success = false;
-                                    deviceName = "";
-                                    volumeName = "";
-                                    char name[B_FILE_NAME_LENGTH];
-                                    if ( vol.GetName( name ) >= B_OK )    // disk is currently mounted
-                                    {
-                                        volumeName = name;
-                                        dev_t dev = vol.Device();
-                                        fs_info info;
-                                        if ( fs_stat_dev( dev, &info ) == B_OK )
-                                        {
-                                            success = true;
-                                            deviceName = info.device_name;
-                                            if ( vol.IsReadOnly() )
-                                            {
-                                                int i_dev = open( info.device_name, O_RDONLY );
-                                                if ( i_dev >= 0 )
-                                                {
-                                                    device_geometry g;
-                                                    if ( ioctl( i_dev, B_GET_GEOMETRY, &g, sizeof( g ) ) >= 0 )
-                                                    isCDROM = ( g.device_type == B_CD );
-                                                    close( i_dev );
-                                                }
-                                            }
-                                        }
-                                     }
-                                    
-                                    if( success && isCDROM )
-                                    {
-                                        BMessage msg( OPEN_DVD );
-                                        msg.AddString( "device", deviceName.String() );
-                                        PostMessage( &msg );
-                                        add = false;
-                                    }
-                                     break;
-                                }
-                                else
-                                {
-                                     vol.Unset();
-                                    status = volRoster.GetNextVolume( &vol );
-                                }
-                            }
+                               // has the user dropped a dvd disk icon?
+                                       // TODO: this code does not work for the following situation:
+                                       // if the user dropped the icon for his partition containing
+                                       // all his mp3 files, this routine will not do anything, because
+                                       // the folder that was dropped is a root folder, but no DVD drive
+                                                       if ( dir.IsRootDirectory() )
+                                                       {
+                                                               BVolumeRoster volRoster;
+                                                               BVolume vol;
+                                                               BDirectory volumeRoot;
+                                                               status_t status = volRoster.GetNextVolume( &vol );
+                                                               while ( status == B_NO_ERROR )
+                                                               {
+                                                                       if ( vol.GetRootDirectory( &volumeRoot ) == B_OK
+                                                                                && dir == volumeRoot )
+                                                                       {
+                                                                               BString volumeName;
+                                                                               BString deviceName;
+                                                                               bool isCDROM;
+                                                                               if ( get_volume_info( vol, volumeName, isCDROM, deviceName )
+                                                                                        && isCDROM )
+                                                                               {
+                                                                                       BMessage msg( OPEN_DVD );
+                                                                                       msg.AddString( "device", deviceName.String() );
+                                                                                       PostMessage( &msg );
+                                                                                       add = false;
+                                                                               }
+                                                                               break;
+                                                                       }
+                                                                       else
+                                                                       {
+                                                                               vol.Unset();
+                                                                               status = volRoster.GetNextVolume( &vol );
+                                                                       }
+                                                               }
+                                                       }
+                               else
+                               {
+                                       // add all files from the dropped folder
+                                       // TODO: do this recursively
+                                       dir.Rewind();
+                                       add = false;
+                                       BEntry entry;
+                                       while ( dir.GetNextEntry( &entry ) == B_OK )
+                                       {
+                                                                       // ", 0" is because we receive the files in reverse order
+                                               if ( !entry.IsDirectory() && entry.GetPath( &path ) == B_OK )
+                                                   files.AddItem( new BString( path.Path() ), 0 );
+                                       }
+                               }
                         }
                         if( add )
                         {
-                            files.AddItem( new BString( (char*)path.Path() ) );
+                            files.AddItem( new BString( path.Path() ) );
                         }
                     }
                 }
                 // give the list to VLC
-                p_wrapper->OpenFiles(&files, replace);
+                // BString objects allocated here will be deleted there
+                int32 index;
+                if ( p_message->FindInt32("drop index", &index) != B_OK )
+                       index = -1;
+                p_wrapper->OpenFiles( &files, replace, index );
                 _UpdatePlaylist();
             }
             break;
@@ -625,7 +739,7 @@ bool InterfaceWindow::QuitRequested()
     p_mediaControl->SetStatus(NOT_STARTED_S, DEFAULT_RATE);
 
     /* Save interface settings */
-    BRect frame = Frame();
+/*    BRect frame = Frame();
     config_PutInt( p_intf, "beos-intf-width", (int)frame.Width() );
     config_PutInt( p_intf, "beos-intf-height", (int)frame.Height() );
     config_PutInt( p_intf, "beos-intf-xpos", (int)frame.left );
@@ -649,9 +763,10 @@ bool InterfaceWindow::QuitRequested()
         config_PutInt( p_intf, "beos-messages-ypos", (int)frame.top );
         config_PutInt( p_intf, "beos-messages-show", !fMessagesWindow->IsHidden() );
         fMessagesWindow->Unlock();
-    }
+    }*/
     config_SaveConfigFile( p_intf, "beos" );
-    
+       _StoreSettings();
+   
     p_intf->b_die = 1;
 
     return( true );
@@ -666,9 +781,9 @@ void InterfaceWindow::UpdateInterface()
     {
         if ( acquire_sem( p_mediaControl->fScrubSem ) == B_OK )
         {
-            p_wrapper->SetTimeAsFloat(p_mediaControl->GetSeekTo());
+            p_wrapper->SetTimeAsFloat( p_mediaControl->GetSeekTo() );
         }
-        else if ( Lock() )
+        else if ( LockWithTimeout( INTERFACE_LOCKING_TIMEOUT ) == B_OK )
         {
             p_mediaControl->SetEnabled( true );
             bool hasTitles = p_wrapper->HasTitles();
@@ -696,7 +811,7 @@ void InterfaceWindow::UpdateInterface()
             Unlock();
         }
         // update playlist as well
-        if ( fPlaylistWindow->Lock() )
+        if ( fPlaylistWindow->LockWithTimeout( INTERFACE_LOCKING_TIMEOUT ) == B_OK )
         {
             fPlaylistWindow->UpdatePlaylist();
             fPlaylistWindow->Unlock();
@@ -706,7 +821,7 @@ void InterfaceWindow::UpdateInterface()
     {
         _SetMenusEnabled( false );
         if( !( p_wrapper->PlaylistSize() > 0 ) )
-           p_mediaControl->SetEnabled( false );
+            p_mediaControl->SetEnabled( false );
         else
             p_mediaControl->SetProgress( 0 );
     }
@@ -718,8 +833,11 @@ void InterfaceWindow::UpdateInterface()
     {
         p_wrapper->SetVolume( i_volume );
     }
-    
-    fMessagesWindow->UpdateMessages();
+
+       // strangly, someone is calling this function even after the object has been destructed!
+       // even more strangly, this workarround seems to work
+       if (fMessagesWindow)
+           fMessagesWindow->UpdateMessages();
 
     fLastUpdateTime = system_time();
 }
@@ -758,30 +876,30 @@ InterfaceWindow::_SetMenusEnabled(bool hasFile, bool hasChapters, bool hasTitles
         hasChapters = false;
         hasTitles = false;
     }
-    if (Lock())
+    if ( LockWithTimeout( INTERFACE_LOCKING_TIMEOUT ) == B_OK)
     {
-        if (fNextChapterMI->IsEnabled() != hasChapters)
-            fNextChapterMI->SetEnabled(hasChapters);
-        if (fPrevChapterMI->IsEnabled() != hasChapters)
-            fPrevChapterMI->SetEnabled(hasChapters);
-        if (fChapterMenu->IsEnabled() != hasChapters)
-            fChapterMenu->SetEnabled(hasChapters);
-        if (fNextTitleMI->IsEnabled() != hasTitles)
-            fNextTitleMI->SetEnabled(hasTitles);
-        if (fPrevTitleMI->IsEnabled() != hasTitles)
-            fPrevTitleMI->SetEnabled(hasTitles);
-        if (fTitleMenu->IsEnabled() != hasTitles)
-            fTitleMenu->SetEnabled(hasTitles);
-        if (fAudioMenu->IsEnabled() != hasFile)
-            fAudioMenu->SetEnabled(hasFile);
-        if (fNavigationMenu->IsEnabled() != hasFile)
-            fNavigationMenu->SetEnabled(hasFile);
-        if (fLanguageMenu->IsEnabled() != hasFile)
-            fLanguageMenu->SetEnabled(hasFile);
-        if (fSubtitlesMenu->IsEnabled() != hasFile)
-            fSubtitlesMenu->SetEnabled(hasFile);
-        if (fSpeedMenu->IsEnabled() != hasFile)
-            fSpeedMenu->SetEnabled(hasFile);
+        if ( fNextChapterMI->IsEnabled() != hasChapters )
+             fNextChapterMI->SetEnabled( hasChapters );
+        if ( fPrevChapterMI->IsEnabled() != hasChapters )
+             fPrevChapterMI->SetEnabled( hasChapters );
+        if ( fChapterMenu->IsEnabled() != hasChapters )
+             fChapterMenu->SetEnabled( hasChapters );
+        if ( fNextTitleMI->IsEnabled() != hasTitles )
+             fNextTitleMI->SetEnabled( hasTitles );
+        if ( fPrevTitleMI->IsEnabled() != hasTitles )
+             fPrevTitleMI->SetEnabled( hasTitles );
+        if ( fTitleMenu->IsEnabled() != hasTitles )
+             fTitleMenu->SetEnabled( hasTitles );
+        if ( fAudioMenu->IsEnabled() != hasFile )
+             fAudioMenu->SetEnabled( hasFile );
+        if ( fNavigationMenu->IsEnabled() != hasFile )
+             fNavigationMenu->SetEnabled( hasFile );
+        if ( fLanguageMenu->IsEnabled() != hasFile )
+             fLanguageMenu->SetEnabled( hasFile );
+        if ( fSubtitlesMenu->IsEnabled() != hasFile )
+             fSubtitlesMenu->SetEnabled( hasFile );
+        if ( fSpeedMenu->IsEnabled() != hasFile )
+             fSpeedMenu->SetEnabled( hasFile );
         Unlock();
     }
 }
@@ -820,20 +938,133 @@ InterfaceWindow::_InputStreamChanged()
     p_wrapper->SetVolume( p_mediaControl->GetVolume() );
 }
 
+/*****************************************************************************
+ * InterfaceWindow::_ShowFilePanel
+ *****************************************************************************/
 void
-make_sure_frame_is_within_limits( BRect& frame, float minWidth, float minHeight,
-                                  float maxWidth, float maxHeight )
+InterfaceWindow::_ShowFilePanel( uint32 command, const char* windowTitle )
 {
-    if ( frame.Width() < minWidth )
-        frame.right = frame.left + minWidth;
-    if ( frame.Height() < minHeight )
-        frame.bottom = frame.top + minHeight;
-    if ( frame.Width() > maxWidth )
-        frame.right = frame.left + maxWidth;
-    if ( frame.Height() > maxHeight )
-        frame.bottom = frame.top + maxHeight;
+       if( !fFilePanel )
+       {
+               fFilePanel = new BFilePanel();
+               fFilePanel->SetTarget( this );
+       }
+       fFilePanel->Window()->SetTitle( windowTitle );
+       BMessage message( command );
+       fFilePanel->SetMessage( &message );
+       if ( !fFilePanel->IsShowing() )
+       {
+               fFilePanel->Refresh();
+               fFilePanel->Show();
+       }
+}
+
+// set_window_pos
+void
+set_window_pos( BWindow* window, BRect frame )
+{
+       // sanity checks: make sure window is not too big/small
+       // and that it's not off-screen
+       float minWidth, maxWidth, minHeight, maxHeight;
+       window->GetSizeLimits( &minWidth, &maxWidth, &minHeight, &maxHeight );
+
+       make_sure_frame_is_within_limits( frame,
+                                                                         minWidth, minHeight, maxWidth, maxHeight );
+       if ( make_sure_frame_is_on_screen( frame ) )
+       {
+               window->MoveTo( frame.LeftTop() );
+               window->ResizeTo( frame.Width(), frame.Height() );
+       }
+}
+
+// set_window_pos
+void
+launch_window( BWindow* window, bool showing )
+{
+       if ( window->Lock() )
+       {
+               if ( showing )
+               {
+                       if ( window->IsHidden() )
+                               window->Show();
+               }
+               else
+               {
+                       if ( !window->IsHidden() )
+                               window->Hide();
+               }
+               window->Unlock();
+       }
+}
+
+/*****************************************************************************
+ * InterfaceWindow::_RestoreSettings
+ *****************************************************************************/
+void
+InterfaceWindow::_RestoreSettings()
+{
+       if ( load_settings( fSettings, "interface_settings", "VideoLAN Client" ) == B_OK )
+       {
+               BRect frame;
+               if ( fSettings->FindRect( "main frame", &frame ) == B_OK )
+                       set_window_pos( this, frame );
+               if (fSettings->FindRect( "playlist frame", &frame ) == B_OK )
+                       set_window_pos( fPlaylistWindow, frame );
+               if (fSettings->FindRect( "messages frame", &frame ) == B_OK )
+                       set_window_pos( fMessagesWindow, frame );
+               if (fSettings->FindRect( "settings frame", &frame ) == B_OK )
+                       set_window_pos( fPreferencesWindow, frame );
+               
+               bool showing;
+               if ( fSettings->FindBool( "playlist showing", &showing ) == B_OK )
+                       launch_window( fPlaylistWindow, showing );
+               if ( fSettings->FindBool( "messages showing", &showing ) == B_OK )
+                       launch_window( fMessagesWindow, showing );
+               if ( fSettings->FindBool( "settings showing", &showing ) == B_OK )
+                       launch_window( fPreferencesWindow, showing );
+       }
 }
 
+/*****************************************************************************
+ * InterfaceWindow::_StoreSettings
+ *****************************************************************************/
+void
+InterfaceWindow::_StoreSettings()
+{
+       if ( fSettings->ReplaceRect( "main frame", Frame() ) != B_OK )
+               fSettings->AddRect( "main frame", Frame() );
+       if ( fPlaylistWindow->Lock() )
+       {
+               if (fSettings->ReplaceRect( "playlist frame", fPlaylistWindow->Frame() ) != B_OK)
+                       fSettings->AddRect( "playlist frame", fPlaylistWindow->Frame() );
+               if (fSettings->ReplaceBool( "playlist showing", !fPlaylistWindow->IsHidden() ) != B_OK)
+                       fSettings->AddBool( "playlist showing", !fPlaylistWindow->IsHidden() );
+               fPlaylistWindow->Unlock();
+       }
+       if ( fMessagesWindow->Lock() )
+       {
+               if (fSettings->ReplaceRect( "messages frame", fMessagesWindow->Frame() ) != B_OK)
+                       fSettings->AddRect( "messages frame", fMessagesWindow->Frame() );
+               if (fSettings->ReplaceBool( "messages showing", !fMessagesWindow->IsHidden() ) != B_OK)
+                       fSettings->AddBool( "messages showing", !fMessagesWindow->IsHidden() );
+               fMessagesWindow->Unlock();
+       }
+       if ( fPreferencesWindow->Lock() )
+       {
+               if (fSettings->ReplaceRect( "settings frame", fPreferencesWindow->Frame() ) != B_OK)
+                       fSettings->AddRect( "settings frame", fPreferencesWindow->Frame() );
+               if (fSettings->ReplaceBool( "settings showing", !fPreferencesWindow->IsHidden() ) != B_OK)
+                       fSettings->AddBool( "settings showing", !fPreferencesWindow->IsHidden() );
+               fPreferencesWindow->Unlock();
+       }
+       save_settings( fSettings, "interface_settings", "VideoLAN Client" );
+}
+
+
+
+
+
+
 /*****************************************************************************
  * CDMenu::CDMenu
  *****************************************************************************/
@@ -855,9 +1086,9 @@ CDMenu::~CDMenu()
 void CDMenu::AttachedToWindow(void)
 {
     // remove all items
-    while (BMenuItem* item = RemoveItem(0L))
+    while ( BMenuItem* item = RemoveItem( 0L ) )
         delete item;
-    GetCD("/dev/disk");
+    GetCD( "/dev/disk" );
     BMenu::AttachedToWindow();
 }
 
@@ -866,54 +1097,26 @@ void CDMenu::AttachedToWindow(void)
  *****************************************************************************/
 int CDMenu::GetCD( const char *directory )
 {
-    BVolumeRoster *volRoster;
-    BVolume       *vol;
-    BDirectory    *dir;
-    int           status;
-    int           mounted;   
-    char          name[B_FILE_NAME_LENGTH]; 
-    fs_info       info;
-    dev_t         dev;
-    
-    volRoster = new BVolumeRoster();
-    vol = new BVolume();
-    dir = new BDirectory();
-    status = volRoster->GetNextVolume(vol);
-    status = vol->GetRootDirectory(dir);
-    while (status ==  B_NO_ERROR)
-    {
-        mounted = vol->GetName(name);    
-        if ((mounted == B_OK) && /* Disk is currently Mounted */
-            (vol->IsReadOnly()) ) /* Disk is read-only */
-        {
-            dev = vol->Device();
-            fs_stat_dev(dev, &info);
-            
-            device_geometry g;
-            int i_dev;
-            i_dev = open( info.device_name, O_RDONLY );
-           
-            if( i_dev >= 0 )
-            {
-                if( ioctl(i_dev, B_GET_GEOMETRY, &g, sizeof(g)) >= 0 )
-                {
-                    if( g.device_type == B_CD ) //ensure the drive is a CD-ROM
-                    {
-                        BMessage *msg;
-                        msg = new BMessage( OPEN_DVD );
-                        msg->AddString( "device", info.device_name );
-                        BMenuItem *menu_item;
-                        menu_item = new BMenuItem( name, msg );
-                        AddItem( menu_item );
-                    }
-                    close(i_dev);
-                }
-            }
-         }
-         vol->Unset();
-        status = volRoster->GetNextVolume(vol);
-    }
-    return 0;
+       BVolumeRoster volRoster;
+       BVolume vol;
+       BDirectory dir;
+       status_t status = volRoster.GetNextVolume( &vol );
+       while ( status ==  B_NO_ERROR )
+       {
+               BString deviceName;
+               BString volumeName;
+               bool isCDROM;
+               if ( get_volume_info( vol, volumeName, isCDROM, deviceName )
+                        && isCDROM )
+               {
+                       BMessage* msg = new BMessage( OPEN_DVD );
+                       msg->AddString( "device", deviceName.String() );
+                       BMenuItem* item = new BMenuItem( volumeName.String(), msg );
+                       AddItem( item );
+               }
+               vol.Unset();
+               status = volRoster.GetNextVolume( &vol );
+       }
 }
 
 /*****************************************************************************
@@ -944,32 +1147,17 @@ void LanguageMenu::AttachedToWindow()
         delete item;
 
     SetRadioMode( true );
-    _GetChannels();
+       if ( BList *list = p_wrapper->GetChannels( kind ) )
+       {
+           for ( int32 i = 0; BMenuItem* item = (BMenuItem*)list->ItemAt( i ); i++ )
+               AddItem( item );
+           
+           if ( list->CountItems() > 1 )
+               AddItem( new BSeparatorItem(), 1 );
+       }
     BMenu::AttachedToWindow();
 }
 
-/*****************************************************************************
- * LanguageMenu::_GetChannels
- *****************************************************************************/
-void LanguageMenu::_GetChannels()
-{
-    BMenuItem *item;
-    BList *list;
-    
-    if( ( list = p_wrapper->GetChannels( kind ) ) == NULL )
-        return;
-    
-    for( int i = 0; i < list->CountItems(); i++ )
-    {
-        item = (BMenuItem*)list->ItemAt( i );
-        AddItem( item );
-    }
-    
-    if( list->CountItems() > 1 )
-        AddItem( new BSeparatorItem(), 1 );
-}
-
-
 /*****************************************************************************
  * TitleMenu::TitleMenu
  *****************************************************************************/
@@ -991,21 +1179,14 @@ TitleMenu::~TitleMenu()
  *****************************************************************************/
 void TitleMenu::AttachedToWindow()
 {
-    BMenuItem *item;
-    BList *list;
-
-    while( ( item = RemoveItem( 0L ) ) )
+    while( BMenuItem* item = RemoveItem( 0L ) )
         delete item;
-    
-    if( ( list = p_intf->p_sys->p_wrapper->GetTitles() ) == NULL )
-        return;
-    
-    for( int i = 0; i < list->CountItems(); i++ )
-    {
-        item = (BMenuItem*)list->ItemAt( i );
-        AddItem( item );
-    }
-    
+
+    if ( BList *list = p_intf->p_sys->p_wrapper->GetTitles() )
+       {    
+               for( int i = 0; BMenuItem* item = (BMenuItem*)list->ItemAt( i ); i++ )
+               AddItem( item );
+       }
     BMenu::AttachedToWindow();
 }
 
@@ -1031,21 +1212,80 @@ ChapterMenu::~ChapterMenu()
  *****************************************************************************/
 void ChapterMenu::AttachedToWindow()
 {
-    BMenuItem *item;
-    BList *list;
-
-    while( ( item = RemoveItem( 0L ) ) )
+    while( BMenuItem* item = RemoveItem( 0L ) )
         delete item;
-    
-    if( ( list = p_intf->p_sys->p_wrapper->GetChapters() ) == NULL )
-        return;
-    
-    for( int i = 0; i < list->CountItems(); i++ )
-    {
-        item = (BMenuItem*)list->ItemAt( i );
-        AddItem( item );
-    }
+
+    if ( BList* list = p_intf->p_sys->p_wrapper->GetChapters() )
+       {    
+           for( int i = 0; BMenuItem* item = (BMenuItem*)list->ItemAt( i ); i++ )
+               AddItem( item );
+       }
     
     BMenu::AttachedToWindow();
 }
 
+
+
+
+
+
+
+
+
+/*****************************************************************************
+ * load_settings
+ *****************************************************************************/
+status_t
+load_settings( BMessage* message, const char* fileName, const char* folder )
+{
+       status_t ret = B_BAD_VALUE;
+       if ( message )
+       {
+               BPath path;
+               if ( ( ret = find_directory( B_USER_SETTINGS_DIRECTORY, &path ) ) == B_OK )
+               {
+                       // passing folder is optional
+                       if ( folder )
+                               ret = path.Append( folder );
+                       if ( ret == B_OK && ( ret = path.Append( fileName ) ) == B_OK )
+                       {
+                               BFile file( path.Path(), B_READ_ONLY );
+                               if ( ( ret = file.InitCheck() ) == B_OK )
+                               {
+                                       ret = message->Unflatten( &file );
+                                       file.Unset();
+                               }
+                       }
+               }
+       }
+       return ret;
+}
+
+/*****************************************************************************
+ * save_settings
+ *****************************************************************************/
+status_t
+save_settings( BMessage* message, const char* fileName, const char* folder )
+{
+       status_t ret = B_BAD_VALUE;
+       if ( message )
+       {
+               BPath path;
+               if ( ( ret = find_directory( B_USER_SETTINGS_DIRECTORY, &path ) ) == B_OK )
+               {
+                       // passing folder is optional
+                       if ( folder && ( ret = path.Append( folder ) ) == B_OK )
+                               ret = create_directory( path.Path(), 0777 );
+                       if ( ret == B_OK && ( ret = path.Append( fileName ) ) == B_OK )
+                       {
+                               BFile file( path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE );
+                               if ( ( ret = file.InitCheck() ) == B_OK )
+                               {
+                                       ret = message->Flatten( &file );
+                                       file.Unset();
+                               }
+                       }
+               }
+       }
+       return ret;
+}
index 53af47b..b5c503a 100644 (file)
@@ -2,7 +2,7 @@
  * InterfaceWindow.h: BeOS interface window class prototype
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: InterfaceWindow.h,v 1.10 2003/01/25 20:15:41 titer Exp $
+ * $Id: InterfaceWindow.h,v 1.11 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Tony Castley <tcastley@mail.powerup.com.au>
@@ -36,6 +36,7 @@ class PlayListWindow;
 class BFilePanel;
 class PreferencesWindow;
 class MessagesWindow;
+class VlcWrapper;
 
 class CDMenu : public BMenu
 {
@@ -60,8 +61,6 @@ class LanguageMenu : public BMenu
     virtual void            AttachedToWindow();
 
  private:
-            void            _GetChannels();
-
     VlcWrapper *            p_wrapper;
     int                     kind;
 };
@@ -115,13 +114,16 @@ class InterfaceWindow : public BWindow
                                               bool hasTitles = false );
             void            _UpdateSpeedMenu( int rate );
             void            _InputStreamChanged();
+            void                       _ShowFilePanel( uint32 command,
+                                                                       const char* windowTitle );
+                       void                    _RestoreSettings();
+                       void                    _StoreSettings();
 
     intf_thread_t*          p_intf;
     es_descriptor_t*        p_spu_es;
 
     bool                    fPlaylistIsEmpty;
     BFilePanel*             fFilePanel;
-    BFilePanel*             fSubtitlesPanel;
     PlayListWindow*         fPlaylistWindow;
     PreferencesWindow*      fPreferencesWindow;
     MessagesWindow*         fMessagesWindow;
@@ -143,8 +145,20 @@ class InterfaceWindow : public BWindow
     BMenu*                  fSpeedMenu;
     BMenu*                  fShowMenu;
     bigtime_t               fLastUpdateTime;
-    
-    VlcWrapper * p_wrapper;
+       BMessage*                               fSettings;      // we keep the message arround
+                                                                               // for forward compatibility
+    VlcWrapper*                                p_wrapper;
 };
 
+
+// some global support functions
+status_t load_settings( BMessage* message,
+                                               const char* fileName,
+                                               const char* folder = NULL );
+
+status_t save_settings( BMessage* message,
+                                               const char* fileName,
+                                               const char* folder = NULL );
+
+
 #endif    // BEOS_INTERFACE_WINDOW_H
index 130cb16..d8ca81e 100644 (file)
@@ -2,7 +2,7 @@
  * ListViews.h: BeOS interface list view class implementation
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: ListViews.cpp,v 1.2 2003/01/22 01:13:22 titer Exp $
+ * $Id: ListViews.cpp,v 1.3 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Stephan Aßmus <stippi@yellowbites.com>
  *
@@ -22,6 +22,7 @@
  *****************************************************************************/
 
 #include <stdio.h>
+#include <malloc.h>
 
 #include <Bitmap.h>
 #include <String.h>
@@ -128,6 +129,7 @@ DragSortableListView::DragSortableListView( BRect frame, const char* name,
                                                                                        list_view_type type, uint32 resizingMode,
                                                                                        uint32 flags )
        : BListView( frame, name, type, resizingMode, flags ),
+         fDropRect( 0.0, 0.0, -1.0, -1.0 ),
          fDropIndex( -1 )
 {
        SetViewColor( B_TRANSPARENT_32_BIT );
@@ -168,6 +170,12 @@ DragSortableListView::Draw( BRect updateRect )
                SetLowColor( 255, 255, 255, 255 );
                FillRect( updateRect, B_SOLID_LOW );
        }
+       // drop anticipation indication
+       if ( fDropRect.IsValid() )
+       {
+               SetHighColor( 255, 0, 0, 255 );
+               StrokeRect( fDropRect );
+       }
 }
 
 /*****************************************************************************
@@ -176,7 +184,6 @@ DragSortableListView::Draw( BRect updateRect )
 bool
 DragSortableListView::InitiateDrag( BPoint point, int32 index, bool )
 {
-return false;
        bool success = false;
        BListItem* item = ItemAt( CurrentSelection( 0 ) );
        if ( !item )
@@ -197,7 +204,7 @@ return false;
                int32 numItems;
                bool fade = false;
                for (numItems = 0; BListItem* item = ItemAt( CurrentSelection( numItems ) ); numItems++) {
-                       dragRect.bottom += item->Height();
+                       dragRect.bottom += ceilf( item->Height() ) + 1.0;
                        if ( dragRect.Height() > MAX_DRAG_HEIGHT ) {
                                fade = true;
                                dragRect.bottom = MAX_DRAG_HEIGHT;
@@ -216,7 +223,7 @@ return false;
                                for ( int32 i = 0; i < numItems; i++ ) {
                                        int32 index = CurrentSelection( i );
                                        BListItem* item = ItemAt( index );
-                                       itemBounds.bottom = itemBounds.top + item->Height() - 1.0;
+                                       itemBounds.bottom = itemBounds.top + ceilf( item->Height() );
                                        if ( itemBounds.bottom > dragRect.bottom )
                                                itemBounds.bottom = dragRect.bottom;
                                        DrawListItem( v, index, itemBounds );
@@ -281,49 +288,40 @@ DragSortableListView::WindowActivated( bool active )
 void
 DragSortableListView::MessageReceived(BMessage* message)
 {
-       BListItem *item = NULL;
-       DragSortableListView *list = NULL;
-       if ( message->FindPointer( "list", (void **)&list ) == B_OK
-                && list == this )
+       switch ( message->what )
        {
-               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++ )
+               case B_MODIFIERS_CHANGED:
+                       ModifiersChanged();
+                       break;
+               case B_SIMPLE_DATA:
                {
-                       
-                       if ( HasItem( item ) )
+                       DragSortableListView *list = NULL;
+                       if ( message->FindPointer( "list", (void **)&list ) == B_OK
+                                && list == this )
                        {
-                               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 )
+                               int32 count = CountItems();
+                               if ( fDropIndex < 0 || fDropIndex > count )
+                                       fDropIndex = count;
+                               BList items;
+                               int32 index;
+                               for ( int32 i = 0; message->FindInt32( "index", i, &index ) == B_OK; i++ )
+                                       if ( BListItem* item = ItemAt(index) )
+                                               items.AddItem( (void*)item );
+                               if ( items.CountItems() > 0 )
                                {
-                                       if ( AddItem( itemToAdd, fDropIndex ) )
-                                               Select( IndexOf( itemToAdd ), true );
+                                       if ( modifiers() & B_SHIFT_KEY )
+                                               CopyItems( items, fDropIndex );
                                        else
-                                               delete itemToAdd;
+                                               MoveItems( items, fDropIndex );
                                }
+                               fDropIndex = -1;
                        }
-                       fDropIndex++;
+                       break;
                }
-               fDropIndex = -1;
-       } else
-               BListView::MessageReceived( message );
+               default:
+                       BListView::MessageReceived( message );
+                       break;
+       }
 }
 
 /*****************************************************************************
@@ -334,120 +332,46 @@ DragSortableListView::MouseMoved(BPoint where, uint32 transit, const BMessage *m
 {
        if ( msg && msg->what == B_SIMPLE_DATA )
        {
+               bool replaceAll = !msg->HasPointer("list") && !(modifiers() & B_SHIFT_KEY);
                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)
+                               if ( replaceAll )
                                {
-                                       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);
-                                       }
+                                       BRect r( Bounds() );
+                                       r.bottom--;     // compensate for scrollbar offset
+                                       _SetDropAnticipationRect( r );
+                                       fDropIndex = -1;
                                }
-                               // 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;
-                                       }
+                                       // offset where by half of item height
+                                       BRect r( ItemFrame( 0 ) );
+                                       where.y += r.Height() / 2.0;
+       
+                                       int32 index = IndexOf( where );
+                                       if ( index < 0 )
+                                               index = CountItems();
+                                       _SetDropIndex( index );
                                }
-                               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:
+                               _RemoveDropAnticipationRect();
                                break;
                }
+               // remember drag message
+               // this is needed to react on modifier changes
+               fDragMessageCopy = *msg;
        }
        else
+       {
+               _RemoveDropAnticipationRect();
                BListView::MouseMoved(where, transit, msg);
+       }
 }
 
 /*****************************************************************************
@@ -457,8 +381,7 @@ void
 DragSortableListView::MouseUp( BPoint where )
 {
        // remove drop mark
-       if ( fDropIndex >= 0 && fDropIndex < CountItems() )
-               InvalidateItem( fDropIndex );
+       _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
        BListView::MouseUp( where );
 }
 
@@ -471,25 +394,204 @@ DragSortableListView::DrawItem( BListItem *item, BRect itemFrame, bool complete
        DrawListItem( this, IndexOf( item ), itemFrame );
 }
 
+/*****************************************************************************
+ * DragSortableListView::ModifiersChaned
+ *****************************************************************************/
+void
+DragSortableListView::ModifiersChanged()
+{
+       BPoint where;
+       uint32 buttons;
+       GetMouse( &where, &buttons, false );
+       uint32 transit = Bounds().Contains( where ) ? B_INSIDE_VIEW : B_OUTSIDE_VIEW;
+       MouseMoved( where, transit, &fDragMessageCopy );
+}
+
+/*****************************************************************************
+ * DragSortableListView::MoveItems
+ *****************************************************************************/
+void
+DragSortableListView::MoveItems( BList& items, int32 index )
+{
+       DeselectAll();
+       // we remove the items while we look at them, the insertion index is decreased
+       // when the items index is lower, so that we insert at the right spot after
+       // removal
+       BList removedItems;
+       int32 count = items.CountItems();
+       for ( int32 i = 0; i < count; i++ )
+       {
+               BListItem* item = (BListItem*)items.ItemAt( i );
+               int32 removeIndex = IndexOf( item );
+               if ( RemoveItem( item ) && removedItems.AddItem( (void*)item ) )
+               {
+                       if ( removeIndex < index )
+                               index--;
+               }
+               // else ??? -> blow up
+       }
+       for ( int32 i = 0; BListItem* item = (BListItem*)removedItems.ItemAt( i ); i++ )
+       {
+               if ( AddItem( item, index ) )
+               {
+                       // after we're done, the newly inserted items will be selected
+                       Select( index, true );
+                       // next items will be inserted after this one
+                       index++;
+               }
+               else
+                       delete item;
+       }
+}
+
+/*****************************************************************************
+ * DragSortableListView::CopyItems
+ *****************************************************************************/
+void
+DragSortableListView::CopyItems( BList& items, int32 index )
+{
+       DeselectAll();
+       // by inserting the items after we copied all items first, we avoid
+       // cloning an item we already inserted and messing everything up
+       // in other words, don't touch the list before we know which items
+       // need to be cloned
+       BList clonedItems;
+       int32 count = items.CountItems();
+       for ( int32 i = 0; i < count; i++ )
+       {
+               BListItem* item = CloneItem( IndexOf( (BListItem*)items.ItemAt( i ) ) );
+               if ( item && !clonedItems.AddItem( (void*)item ) )
+                       delete item;
+       }
+       for ( int32 i = 0; BListItem* item = (BListItem*)clonedItems.ItemAt( i ); i++ )
+       {
+               if ( AddItem( item, index ) )
+               {
+                       // after we're done, the newly inserted items will be selected
+                       Select( index, true );
+                       // next items will be inserted after this one
+                       index++;
+               }
+               else
+                       delete item;
+       }
+}
+
+/*****************************************************************************
+ * DragSortableListView::RemoveItemList
+ *****************************************************************************/
+void
+DragSortableListView::RemoveItemList( BList& items )
+{
+       int32 count = items.CountItems();
+       for ( int32 i = 0; i < count; i++ )
+       {
+               BListItem* item = (BListItem*)items.ItemAt( i );
+               if ( RemoveItem( item ) )
+                       delete item;
+       }
+}
+
+/*****************************************************************************
+ * DragSortableListView::RemoveSelected
+ *****************************************************************************/
+void
+DragSortableListView::RemoveSelected()
+{
+       BList items;
+       for ( int32 i = 0; BListItem* item = ItemAt( CurrentSelection( i ) ); i++ )
+               items.AddItem( (void*)item );
+       RemoveItemList( items );
+}
+
+/*****************************************************************************
+ * DragSortableListView::_SetDropAnticipationRect
+ *****************************************************************************/
+void
+DragSortableListView::_SetDropAnticipationRect( BRect r )
+{
+       if ( fDropRect != r )
+       {
+               if ( fDropRect.IsValid() )
+                       Invalidate( fDropRect );
+               fDropRect = r;
+               if ( fDropRect.IsValid() )
+                       Invalidate( fDropRect );
+       }
+}
+
+/*****************************************************************************
+ * DragSortableListView::_SetDropAnticipationRect
+ *****************************************************************************/
+void
+DragSortableListView::_SetDropIndex( int32 index )
+{
+       if ( fDropIndex != index )
+       {
+               fDropIndex = index;
+               if ( fDropIndex == -1 )
+                       _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
+               else
+               {
+                       int32 count = CountItems();
+                       if ( fDropIndex == count )
+                       {
+                               BRect r;
+                               if ( BListItem* item = ItemAt( count - 1 ) )
+                               {
+                                       r = ItemFrame( count - 1 );
+                                       r.top = r.bottom + 1.0;
+                                       r.bottom = r.top + 1.0;
+                               }
+                               else
+                               {
+                                       r = Bounds();
+                                       r.bottom--;     // compensate for scrollbars moved slightly out of window
+                               }
+                               _SetDropAnticipationRect( r );
+                       }
+                       else
+                       {
+                               BRect r = ItemFrame( fDropIndex );
+                               r.bottom = r.top + 1.0;
+                               _SetDropAnticipationRect( r );
+                       }
+               }
+       }
+}
+
+/*****************************************************************************
+ * DragSortableListView::_RemoveDropAnticipationRect
+ *****************************************************************************/
+void
+DragSortableListView::_RemoveDropAnticipationRect()
+{
+       _SetDropAnticipationRect( BRect( 0.0, 0.0, -1.0, -1.0 ) );
+       _SetDropIndex( -1 );
+}
+
 
 /*****************************************************************************
  * PlaylistView class
  *****************************************************************************/
 PlaylistView::PlaylistView( BRect frame, InterfaceWindow* mainWindow,
-                            VlcWrapper * p_wrapper )
+                            VlcWrapper* wrapper,
+                            BMessage* selectionChangeMessage )
        : 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 )
+         fMainWindow( mainWindow ),
+         fSelectionChangeMessage( selectionChangeMessage ),
+         fVlcWrapper( wrapper )
 {
-    this->p_wrapper = p_wrapper;
 }
 
 PlaylistView::~PlaylistView()
 {
+       delete fSelectionChangeMessage;
 }
 
 /*****************************************************************************
@@ -499,7 +601,34 @@ void
 PlaylistView::AttachedToWindow()
 {
        // get pulse message every two frames
-       Window()->SetPulseRate(80000);
+       Window()->SetPulseRate( 80000 );
+}
+
+/*****************************************************************************
+ * PlaylistView::MessageReceived
+ *****************************************************************************/
+void
+PlaylistView::MessageReceived( BMessage* message)
+{
+       switch ( message->what )
+       {
+               case B_SIMPLE_DATA:
+                       if ( message->HasPointer( "list" ) )
+                       {
+                               // message comes from ourself
+                               DragSortableListView::MessageReceived( message );
+                       }
+                       else
+                       {
+                               // message comes from another app (for example Tracker)
+                               message->AddInt32( "drop index", fDropIndex );
+                               fMainWindow->PostMessage( message, fMainWindow );
+                       }
+                       break;
+               default:
+                       DragSortableListView::MessageReceived( message );
+                       break;
+       }
 }
 
 /*****************************************************************************
@@ -518,7 +647,7 @@ PlaylistView::MouseDown( BPoint where )
                {
                        if ( clicks == 2 )
                        {
-                               p_wrapper->PlaylistJumpTo( i );
+                               fVlcWrapper->PlaylistJumpTo( i );
                                handled = true;
                        }
                        else if ( i == fCurrentIndex )
@@ -544,20 +673,12 @@ PlaylistView::MouseDown( BPoint where )
 void
 PlaylistView::KeyDown( const char* bytes, int32 numBytes )
 {
-       if (numBytes < 1)
+       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 );
-                       }*/
-               }
+               RemoveSelected();
        }
        DragSortableListView::KeyDown( bytes, numBytes );
 }
@@ -568,10 +689,173 @@ PlaylistView::KeyDown( const char* bytes, int32 numBytes )
 void
 PlaylistView::Pulse()
 {
-       if (fMainWindow->IsStopped())
+       if ( fMainWindow->IsStopped() )
                SetPlaying( false );
 }
 
+/*****************************************************************************
+ * PlaylistView::SelectionChanged
+ *****************************************************************************/
+void
+PlaylistView::SelectionChanged()
+{
+       BLooper* looper = Looper();
+       if ( fSelectionChangeMessage && looper )
+       {
+               BMessage message( *fSelectionChangeMessage );
+               looper->PostMessage( &message );
+       }
+}
+
+
+/*****************************************************************************
+ * PlaylistView::MoveItems
+ *****************************************************************************/
+void
+PlaylistView::MoveItems( BList& items, int32 index )
+{
+       DeselectAll();
+       // we remove the items while we look at them, the insertion index is decreased
+       // when the items index is lower, so that we insert at the right spot after
+       // removal
+       if ( fVlcWrapper->PlaylistLock() )
+       {
+               BList removedItems;
+               BList removeItems;
+               int32 count = items.CountItems();
+               int32 indexOriginal = index;
+               // remember currently playing item
+               int32 currentIndex, size;
+               fVlcWrapper->GetPlaylistInfo( currentIndex, size );
+               BListItem* playingItem = ItemAt( currentIndex );
+               // collect item pointers for removal by index
+               for ( int32 i = 0; i < count; i++ )
+               {
+                       int32 removeIndex = IndexOf( (BListItem*)items.ItemAt( i ) );
+                       void* item = fVlcWrapper->PlaylistItemAt( removeIndex );
+                       if ( item && removeItems.AddItem( item ) )
+                       {
+                               if ( removeIndex < index )
+                                       index--;
+                       }
+                       // else ??? -> blow up
+               }
+               // actually remove items using pointers
+               for ( int32 i = 0; i < count; i++ )
+               {
+                       void* item = fVlcWrapper->PlaylistRemoveItem( removeItems.ItemAt( i ) );
+                       if ( item && !removedItems.AddItem( item ) )
+                               free( item );
+               }
+               // add items at index
+               for ( int32 i = 0; void* item = removedItems.ItemAt( i ); i++ )
+               {
+                       if ( fVlcWrapper->PlaylistAddItem( item, index ) )
+                               // next items will be inserted after this one
+                               index++;
+                       else
+                               free( item );
+               }
+               // update GUI
+               DragSortableListView::MoveItems( items, indexOriginal );
+               // restore currently playing item
+               for ( int32 i = 0; BListItem* item = ItemAt( i ); i++ )
+               {
+                       if ( item == playingItem )
+                       {
+                               fVlcWrapper->PlaylistSetPlaying( i );
+                               SetCurrent( i );
+                               break;
+                       }
+               }
+               fVlcWrapper->PlaylistUnlock();
+       }
+}
+
+/*****************************************************************************
+ * PlaylistView::CopyItems
+ *****************************************************************************/
+void
+PlaylistView::CopyItems( BList& items, int32 toIndex )
+{
+       DeselectAll();
+       // we remove the items while we look at them, the insertion index is decreased
+       // when the items index is lower, so that we insert at the right spot after
+       // removal
+       if ( fVlcWrapper->PlaylistLock() )
+       {
+               BList clonedItems;
+               int32 count = items.CountItems();
+               // remember currently playing item
+               int32 currentIndex, size;
+               fVlcWrapper->GetPlaylistInfo( currentIndex, size );
+               BListItem* playingItem = ItemAt( currentIndex );
+               // collect cloned item pointers
+               for ( int32 i = 0; i < count; i++ )
+               {
+                       int32 index = IndexOf( (BListItem*)items.ItemAt( i ) );
+                       void* item = fVlcWrapper->PlaylistItemAt( index );
+                       void* cloned = fVlcWrapper->PlaylistCloneItem( item );
+                       if ( cloned && !clonedItems.AddItem( cloned ) )
+                               free( cloned );
+                       
+               }
+               // add cloned items at index
+               int32 index = toIndex;
+               for ( int32 i = 0; void* item = clonedItems.ItemAt( i ); i++ )
+               {
+                       if ( fVlcWrapper->PlaylistAddItem( item, index ) )
+                               // next items will be inserted after this one
+                               index++;
+                       else
+                               free( item );
+               }
+               // update GUI
+               DragSortableListView::CopyItems( items, toIndex );
+               // restore currently playing item
+               for ( int32 i = 0; BListItem* item = ItemAt( i ); i++ )
+               {
+                       if ( item == playingItem )
+                       {
+                               fVlcWrapper->PlaylistSetPlaying( i );
+                               SetCurrent( i );
+                               break;
+                       }
+               }
+               fVlcWrapper->PlaylistUnlock();
+       }
+}
+
+/*****************************************************************************
+ * PlaylistView::RemoveItemList
+ *****************************************************************************/
+void
+PlaylistView::RemoveItemList( BList& items )
+{
+       if ( fVlcWrapper->PlaylistLock() )
+       {
+               // collect item pointers for removal
+               BList removeItems;
+               int32 count = items.CountItems();
+               for ( int32 i = 0; i < count; i++ )
+               {
+                       int32 index = IndexOf( (BListItem*)items.ItemAt( i ) );
+                       void* item = fVlcWrapper->PlaylistItemAt( index );
+                       if ( item && !removeItems.AddItem( item ) )
+                               free( item );
+               }
+               // remove items from playlist
+               count = removeItems.CountItems();
+               for ( int32 i = 0; void* item = removeItems.ItemAt( i ); i++ )
+               {
+                       fVlcWrapper->PlaylistRemoveItem( item );
+               }
+               // update GUI
+               DragSortableListView::RemoveItemList( items );
+               fVlcWrapper->PlaylistUnlock();
+       }
+}
+
 /*****************************************************************************
  * PlaylistView::CloneItem
  *****************************************************************************/
@@ -603,8 +887,10 @@ 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 );
+               int32 index;
+               for ( int32 i = 0; ( index = CurrentSelection( i ) ) >= 0; i++ )
+                       message->AddInt32( "index", index );
+                       // TODO: add refs to message (inter application communication)
        }
 }
 
@@ -634,3 +920,19 @@ PlaylistView::SetPlaying( bool playing )
                InvalidateItem( fCurrentIndex );
        }
 }
+
+/*****************************************************************************
+ * PlaylistView::SetPlaying
+ *****************************************************************************/
+void
+PlaylistView::RebuildList()
+{
+       // remove all items
+       int32 count = CountItems();
+       while ( BListItem* item = RemoveItem( --count ) )
+               delete item;
+       
+       // rebuild listview from VLC's playlist
+       for ( int i = 0; i < fVlcWrapper->PlaylistSize(); i++ )
+               AddItem( new PlaylistItem( fVlcWrapper->PlaylistItemName( i ) ) );
+}
index bbe715c..cc93430 100644 (file)
@@ -2,7 +2,7 @@
  * ListViews.h: BeOS interface list view class prototype
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: ListViews.h,v 1.2 2003/01/22 01:13:22 titer Exp $
+ * $Id: ListViews.h,v 1.3 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Stephan Aßmus <stippi@yellowbites.com>
  *
@@ -73,13 +73,28 @@ class DragSortableListView : public BListView
                                                                          bool complete = false);
 
                                                        // DragSortableListView
+       virtual void                    ModifiersChanged();     // called by window
+
+       virtual void                    MoveItems( BList& items, int32 toIndex );
+       virtual void                    CopyItems( BList& items, int32 toIndex );
+       virtual void                    RemoveItemList( BList& indices );
+                       void                    RemoveSelected(); // uses RemoveItemList()
+
        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;
+                       void                    _SetDropAnticipationRect( BRect r );
+                       void                    _SetDropIndex( int32 index );
+                       void                    _RemoveDropAnticipationRect();
+
+       BRect                                   fDropRect;
+       BMessage                                fDragMessageCopy;
+
+ protected:
+       int32                                   fDropIndex;
 };
 
 // PlaylistView
@@ -88,16 +103,23 @@ class PlaylistView : public DragSortableListView
  public:
                                                        PlaylistView( BRect frame,
                                                                                  InterfaceWindow* mainWindow,
-                                                                                 VlcWrapper * p_wrapper );
+                                                                                 VlcWrapper* wrapper,
+                                                                                 BMessage* selectionChangeMessage = NULL );
                                                        ~PlaylistView();
 
                                                        // BListView
        virtual void                    AttachedToWindow();
+       virtual void                    MessageReceived( BMessage* message );
        virtual void                    MouseDown( BPoint where );
        virtual void                    KeyDown( const char* bytes, int32 numBytes );
        virtual void                    Pulse();
+       virtual void                    SelectionChanged();
 
                                                        // DragSortableListView
+       virtual void                    MoveItems( BList& items, int32 toIndex );
+       virtual void                    CopyItems( BList& items, int32 toIndex );
+       virtual void                    RemoveItemList( BList& indices );
+
        virtual BListItem*              CloneItem( int32 atIndex ) const;
        virtual void                    DrawListItem( BView* owner, int32 index,
                                                                                  BRect itemFrame ) const;
@@ -106,13 +128,15 @@ class PlaylistView : public DragSortableListView
                                                        // PlaylistView
                        void                    SetCurrent( int32 index );
                        void                    SetPlaying( bool playing );
+                       void                    RebuildList();
 
  private:
        int32                                   fCurrentIndex;
        bool                                    fPlaying;
        InterfaceWindow*                fMainWindow;
+       BMessage*                               fSelectionChangeMessage;
        
-       VlcWrapper *            p_wrapper;
+       VlcWrapper*                             fVlcWrapper;
 };
 
 #endif // LIST_VIEWS_H
index ccbb319..32aa9f7 100644 (file)
@@ -2,7 +2,7 @@
  * MediaControlView.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: MediaControlView.cpp,v 1.13 2003/01/25 01:03:44 titer Exp $
+ * $Id: MediaControlView.cpp,v 1.14 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Tony Castley <tony@castley.net>
  *          Stephan Aßmus <stippi@yellowbites.com>
@@ -773,9 +773,11 @@ SeekSlider::ResizeToPreferred()
 void
 SeekSlider::SetPosition(float position)
 {
-    LockLooper();
-       SetValue(fMinValue + (int32)floorf((fMaxValue - fMinValue) * position + 0.5));
-       UnlockLooper();
+       if ( LockLooper() )
+       {
+               SetValue(fMinValue + (int32)floorf((fMaxValue - fMinValue) * position + 0.5));
+               UnlockLooper();
+       }
 }
 
 /*****************************************************************************
@@ -1321,7 +1323,7 @@ PositionInfoView::Pulse()
        {
                int32 index, size;
                p_intf->p_sys->p_wrapper->GetPlaylistInfo( index, size );
-               SetFile( index, size );
+               SetFile( index + 1, size );
                p_intf->p_sys->p_wrapper->TitleInfo( index, size );
                SetTitle( index, size );
                p_intf->p_sys->p_wrapper->ChapterInfo( index, size );
index 716b568..af9d8be 100644 (file)
@@ -2,7 +2,7 @@
  * MessagesWindow.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: MessagesWindow.cpp,v 1.5 2003/01/31 06:45:00 titer Exp $
+ * $Id: MessagesWindow.cpp,v 1.6 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Eric Petit <titer@videolan.org>
  *
@@ -147,17 +147,19 @@ void MessagesWindow::UpdateMessages()
                 case VLC_OBJECT_SOUT: psz_module_type = "stream output"; break;
             }
             
-            fMessagesView->LockLooper();
-            oldLength = fMessagesView->TextLength();
-            BString string;
-            string << p_sub->p_msg[i_start].psz_module << " " << psz_module_type << " : " <<
-                p_sub->p_msg[i_start].psz_msg << "\n";
-            fMessagesView->Insert( string.String() );
-            fMessagesView->SetFontAndColor( oldLength,
-                                            fMessagesView->TextLength(),
-                                            NULL, 0, &color );
-            fMessagesView->Draw( fMessagesView->Bounds() );
-            fMessagesView->UnlockLooper();
+            if ( fMessagesView->LockLooper() )
+            {
+                   oldLength = fMessagesView->TextLength();
+                   BString string;
+                   string << p_sub->p_msg[i_start].psz_module << " " << psz_module_type << " : " <<
+                       p_sub->p_msg[i_start].psz_msg << "\n";
+                   fMessagesView->Insert( string.String() );
+                   fMessagesView->SetFontAndColor( oldLength,
+                                                   fMessagesView->TextLength(),
+                                                   NULL, 0, &color );
+                   fMessagesView->Draw( fMessagesView->Bounds() );
+                   fMessagesView->UnlockLooper();
+            }
             
             /* Scroll at the end */
             if( fScrollBar->LockLooper() )
index be8a271..12a1ef7 100644 (file)
@@ -2,7 +2,7 @@
  * PlayListWindow.cpp: beos interface
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: PlayListWindow.cpp,v 1.6 2003/01/22 01:13:22 titer Exp $
+ * $Id: PlayListWindow.cpp,v 1.7 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
 
 enum
 {
-       MSG_SELECT_ALL          = 'sall',
-       MSG_SELECT_NONE         = 'none',
-       MSG_RANDOMIZE           = 'rndm',
-       MSG_SORT_NAME           = 'srtn',
-       MSG_SORT_PATH           = 'srtp',
-       MSG_REMOVE                      = 'rmov',
-       MSG_REMOVE_ALL          = 'rmal',
+       MSG_SELECT_ALL                  = 'sall',
+       MSG_SELECT_NONE                 = 'none',
+       MSG_RANDOMIZE                   = 'rndm',
+       MSG_SORT_NAME                   = 'srtn',
+       MSG_SORT_PATH                   = 'srtp',
+       MSG_REMOVE                              = 'rmov',
+       MSG_REMOVE_ALL                  = 'rmal',
+
+       MSG_SELECTION_CHANGED   = 'slch',
 };
 
 
@@ -93,32 +95,33 @@ PlayListWindow::PlayListWindow( BRect frame, const char* name,
        // Add the Edit menu
        BMenu *editMenu = new BMenu( "Edit" );
        fMenuBar->AddItem( editMenu );
-       item = new BMenuItem( "Select All",
-                                                 new BMessage( MSG_SELECT_ALL ), 'A' );
-       editMenu->AddItem( item );
-       item = new BMenuItem( "Select None",
-                                                 new BMessage( MSG_SELECT_NONE ), 'A', B_SHIFT_KEY );
-       editMenu->AddItem( item );
+       fSelectAllMI = new BMenuItem( "Select All",
+                                                                 new BMessage( MSG_SELECT_ALL ), 'A' );
+       editMenu->AddItem( fSelectAllMI );
+       fSelectNoneMI = new BMenuItem( "Select None",
+                                                                  new BMessage( MSG_SELECT_NONE ), 'A', B_SHIFT_KEY );
+       editMenu->AddItem( fSelectNoneMI );
 
        editMenu->AddSeparatorItem();
-       item = new BMenuItem( "Sort by Name",
-                                                 new BMessage( MSG_SORT_NAME ), 'N' );
-       editMenu->AddItem( item );
-       item = new BMenuItem( "Sort by Path",
-                                                 new BMessage( MSG_SORT_PATH ), 'P' );
-       editMenu->AddItem( item );
-       item = new BMenuItem( "Randomize",
-                                                 new BMessage( MSG_RANDOMIZE ), 'R' );
-       editMenu->AddItem( item );
+       fSortNameMI = new BMenuItem( "Sort by Name",
+                                                                new BMessage( MSG_SORT_NAME ), 'N' );
+fSortNameMI->SetEnabled( false );
+       editMenu->AddItem( fSortNameMI );
+       fSortPathMI = new BMenuItem( "Sort by Path",
+                                                                new BMessage( MSG_SORT_PATH ), 'P' );
+fSortPathMI->SetEnabled( false );
+       editMenu->AddItem( fSortPathMI );
+       fRandomizeMI = new BMenuItem( "Randomize",
+                                                                 new BMessage( MSG_RANDOMIZE ), 'R' );
+fRandomizeMI->SetEnabled( false );
+       editMenu->AddItem( fRandomizeMI );
        editMenu->AddSeparatorItem();
-       item = new BMenuItem( "Remove",
+       fRemoveMI = new BMenuItem( "Remove",
                                                  new BMessage( MSG_REMOVE ) );
-       editMenu->AddItem( item );
-       item = new BMenuItem( "Remove All",
-                                                 new BMessage( MSG_REMOVE_ALL ) );
-       editMenu->AddItem( item );
-
-editMenu->SetEnabled( false );
+       editMenu->AddItem( fRemoveMI );
+       fRemoveAllMI = new BMenuItem( "Remove All",
+                                                                 new BMessage( MSG_REMOVE_ALL ) );
+       editMenu->AddItem( fRemoveAllMI );
 
        // make menu bar resize to correct height
        float menuWidth, menuHeight;
@@ -130,7 +133,8 @@ editMenu->SetEnabled( false );
        frame.top += fMenuBar->Bounds().IntegerHeight() + 1;
        frame.right -= B_V_SCROLL_BAR_WIDTH;
 
-       fListView = new PlaylistView( frame, fMainWindow, p_wrapper );
+       fListView = new PlaylistView( frame, fMainWindow, p_wrapper,
+                                                                 new BMessage( MSG_SELECTION_CHANGED ) );
        fBackgroundView = new BScrollView( "playlist scrollview",
                                                                           fListView, B_FOLLOW_ALL_SIDES,
                                                                           0, false, true,
@@ -182,8 +186,10 @@ PlayListWindow::MessageReceived( BMessage * p_message )
                        fMainWindow->PostMessage( p_message );
                        break;
                case MSG_SELECT_ALL:
+                       fListView->Select( 0, fListView->CountItems() - 1 );
                        break;
                case MSG_SELECT_NONE:
+                       fListView->DeselectAll();
                        break;
                case MSG_RANDOMIZE:
                        break;
@@ -192,8 +198,17 @@ PlayListWindow::MessageReceived( BMessage * p_message )
                case MSG_SORT_PATH:
                        break;
                case MSG_REMOVE:
+                       fListView->RemoveSelected();
                        break;
                case MSG_REMOVE_ALL:
+                       fListView->Select( 0, fListView->CountItems() - 1 );
+                       fListView->RemoveSelected();
+                       break;
+               case MSG_SELECTION_CHANGED:
+                       _CheckItemsEnableState();
+                       break;
+               case B_MODIFIERS_CHANGED:
+                       fListView->ModifiersChanged();
                        break;
                default:
                        BWindow::MessageReceived( p_message );
@@ -235,16 +250,42 @@ void
 PlayListWindow::UpdatePlaylist( bool rebuild )
 {
        if ( rebuild )
-       {
-               // remove all items
-               int32 count = fListView->CountItems();
-               while ( BListItem* item = fListView->RemoveItem( --count ) )
-                       delete item;
-       
-               // rebuild listview from VLC's playlist
-               for ( int i = 0; i < p_wrapper->PlaylistSize(); i++ )
-                       fListView->AddItem( new PlaylistItem( p_wrapper->PlaylistItemName( i ) ) );
-       }
+               fListView->RebuildList();
        fListView->SetCurrent( p_wrapper->PlaylistCurrent() );
        fListView->SetPlaying( p_wrapper->IsPlaying() );
+
+       _CheckItemsEnableState();
+}
+
+/*****************************************************************************
+ * PlayListWindow::_CheckItemsEnableState
+ *****************************************************************************/
+void
+PlayListWindow::_CheckItemsEnableState() const
+{
+       // check if one item selected
+       int32 test = fListView->CurrentSelection( 0 );
+       bool enable1 = test >= 0;
+       // check if at least two items selected
+//     test = fListView->CurrentSelection( 1 );
+//     bool enable2 = test >= 0;
+       bool notEmpty = fListView->CountItems() > 0;
+       _SetMenuItemEnabled( fSelectAllMI, notEmpty );
+       _SetMenuItemEnabled( fSelectNoneMI, enable1 );
+//     _SetMenuItemEnabled( fSortNameMI, enable2 );
+//     _SetMenuItemEnabled( fSortPathMI, enable2 );
+//     _SetMenuItemEnabled( fRandomizeMI, enable2 );
+       _SetMenuItemEnabled( fRemoveMI, enable1 );
+       _SetMenuItemEnabled( fRemoveAllMI, notEmpty );
+}
+
+/*****************************************************************************
+ * PlayListWindow::_SetMenuItemEnabled
+ *****************************************************************************/
+void
+PlayListWindow::_SetMenuItemEnabled( BMenuItem* item, bool enabled ) const
+{
+       // this check should actally be done in BMenuItem::SetEnabled(), but it is not...
+       if ( item->IsEnabled() != enabled )
+               item->SetEnabled( enabled );
 }
index ee655c3..ed098d6 100644 (file)
@@ -2,7 +2,7 @@
  * PlayListWindow.h: BeOS interface window class prototype
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: PlayListWindow.h,v 1.5 2002/11/27 05:36:41 titer Exp $
+ * $Id: PlayListWindow.h,v 1.6 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Tony Castley <tcastley@mail.powerup.com.au>
@@ -29,8 +29,7 @@
 
 #include <Window.h>
 
-class BListView;
-class CDMenu;
+class BMenuItem;
 class InterfaceWindow;
 class PlaylistView;
 
@@ -53,13 +52,25 @@ class PlayListWindow : public BWindow
                        void                            UpdatePlaylist( bool rebuild = false );
 
  private:      
+                       void                            _CheckItemsEnableState() const;
+                       void                            _SetMenuItemEnabled( BMenuItem* item,
+                                                                                                        bool enabled ) const;
+
                        PlaylistView *      fListView;
                        BView *             fBackgroundView;
                        BMenuBar *          fMenuBar;
                        InterfaceWindow *   fMainWindow;
+
+                       BMenuItem*                      fSelectAllMI;
+                       BMenuItem*                      fSelectNoneMI;
+                       BMenuItem*                      fSortNameMI;
+                       BMenuItem*                      fSortPathMI;
+                       BMenuItem*                      fRandomizeMI;
+                       BMenuItem*                      fRemoveMI;
+                       BMenuItem*                      fRemoveAllMI;
                        
                        intf_thread_t *     p_intf;
-                       VlcWrapper *   p_wrapper;
+                       VlcWrapper *            p_wrapper;
 };
 
 #endif // BEOS_PLAY_LIST_WINDOW_H
index ad385e3..377ab0b 100644 (file)
@@ -2,7 +2,7 @@
  * vout_beos.cpp: beos video output display method
  *****************************************************************************
  * Copyright (C) 2000, 2001 VideoLAN
- * $Id: VideoOutput.cpp,v 1.10 2003/01/24 06:31:56 titer Exp $
+ * $Id: VideoOutput.cpp,v 1.11 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Samuel Hocevar <sam@zoy.org>
 #include <vlc/intf.h>
 #include <vlc/vout.h>
 
-#include "VideoWindow.h"
+#include "InterfaceWindow.h"   // for load/save_settings()
 #include "DrawingTidbits.h"
 #include "MsgVals.h"
 
+#include "VideoWindow.h"
+
 /*****************************************************************************
  * vout_sys_t: BeOS video output method descriptor
  *****************************************************************************
@@ -147,6 +149,99 @@ class BackgroundView : public BView
        VLCView*                                fVideoView;
 };
 
+
+/*****************************************************************************
+ * VideoSettings constructor and destructor
+ *****************************************************************************/
+VideoSettings::VideoSettings()
+       : fVideoSize( SIZE_100 ),
+         fFlags( FLAG_CORRECT_RATIO ),
+         fSettings( new BMessage( 'sett' ) )
+{
+       // read settings from disk
+       status_t ret = load_settings( fSettings, "video_settings", "VideoLAN Client" );
+       if ( ret == B_OK )
+       {
+               uint32 flags;
+               if ( fSettings->FindInt32( "flags", (int32*)&flags ) == B_OK )
+                       SetFlags( flags );
+               uint32 size;
+               if ( fSettings->FindInt32( "video size", (int32*)&size ) == B_OK )
+                       SetVideoSize( size );
+       }
+       else
+       {
+               fprintf( stderr, "error loading video settings: %s\n", strerror( ret ) );
+               
+               // figure out if we should use vertical sync by default
+               BScreen screen(B_MAIN_SCREEN_ID);
+               if (screen.IsValid())
+               {
+                       display_mode mode; 
+                       screen.GetMode(&mode); 
+                       float refresh = (mode.timing.pixel_clock * 1000)
+                                                       / ((mode.timing.h_total)* (mode.timing.v_total)); 
+                       if (refresh < MIN_AUTO_VSYNC_REFRESH)
+                               AddFlags(FLAG_SYNC_RETRACE);
+               }
+       }
+}
+
+VideoSettings::VideoSettings( const VideoSettings& clone )
+       : fVideoSize( clone.VideoSize() ),
+         fFlags( clone.Flags() ),
+         fSettings( NULL )
+{
+}
+
+
+VideoSettings::~VideoSettings()
+{
+       if ( fSettings )
+       {
+               // we are the default settings
+               // and write our settings to disk
+               if (fSettings->ReplaceInt32( "video size", VideoSize() ) != B_OK)
+                       fSettings->AddInt32( "video size", VideoSize() );
+               if (fSettings->ReplaceInt32( "flags", Flags() ) != B_OK)
+                       fSettings->AddInt32( "flags", Flags() );
+
+               status_t ret = save_settings( fSettings, "video_settings", "VideoLAN Client" );
+               if ( ret != B_OK )
+                       fprintf( stderr, "error saving video settings: %s\n", strerror( ret ) );
+               delete fSettings;
+       }
+       else
+       {
+               // we are just a clone of the default settings
+               fDefaultSettings.SetVideoSize( VideoSize() );
+               fDefaultSettings.SetFlags( Flags() );
+       }
+}
+
+/*****************************************************************************
+ * VideoSettings::DefaultSettings
+ *****************************************************************************/
+VideoSettings*
+VideoSettings::DefaultSettings()
+{
+       return &fDefaultSettings;
+}
+
+/*****************************************************************************
+ * VideoSettings::SetVideoSize
+ *****************************************************************************/
+void
+VideoSettings::SetVideoSize( uint32 mode )
+{
+       fVideoSize = mode;
+}
+
+// static variable initialization
+VideoSettings
+VideoSettings::fDefaultSettings;
+
+
 /*****************************************************************************
  * VideoWindow constructor and destructor
  *****************************************************************************/
@@ -155,16 +250,15 @@ VideoWindow::VideoWindow(int v_width, int v_height, BRect frame,
        : BWindow(frame, NULL, B_TITLED_WINDOW, B_NOT_CLOSABLE | B_NOT_MINIMIZABLE),
          i_width(frame.IntegerWidth()),
          i_height(frame.IntegerHeight()),
-         is_zoomed(false),
-         vsync(false),
+         winSize(frame),
          i_buffer(0),
          teardownwindow(false),
          fTrueWidth(v_width),
          fTrueHeight(v_height),
-         fCorrectAspect(true),
          fCachedFeel(B_NORMAL_WINDOW_FEEL),
          fInterfaceShowing(false),
-         fInitStatus(B_ERROR)
+         fInitStatus(B_ERROR),
+         fSettings(new VideoSettings(*VideoSettings::DefaultSettings()))
 {
     p_vout = p_videoout;
     
@@ -176,17 +270,6 @@ VideoWindow::VideoWindow(int v_width, int v_height, BRect frame,
     AddChild(mainView);
     mainView->AddChild(view);
 
-       // figure out if we should use vertical sync by default
-       BScreen screen(this);
-       if (screen.IsValid())
-       {
-               display_mode mode; 
-               screen.GetMode(&mode); 
-               float refresh = (mode.timing.pixel_clock * 1000)
-                                               / ((mode.timing.h_total)* (mode.timing.v_total)); 
-               vsync = (refresh < MIN_AUTO_VSYNC_REFRESH);
-       }
-
        // allocate bitmap buffers
        for (int32 i = 0; i < 3; i++)
                bitmap[i] = NULL;
@@ -204,10 +287,11 @@ VideoWindow::VideoWindow(int v_width, int v_height, BRect frame,
                      (i_height * r.min_height_scale), i_height * r.max_height_scale);
     }
     
-    if( config_GetInt( p_vout, "fullscreen" ) )
-    {
-        BWindow::Zoom();;
-    }
+       // vlc settings override settings from disk
+       if (config_GetInt(p_vout, "fullscreen"))
+               fSettings->AddFlags(VideoSettings::FLAG_FULL_SCREEN);
+
+    _SetToSettings();
 }
 
 VideoWindow::~VideoWindow()
@@ -217,6 +301,7 @@ VideoWindow::~VideoWindow()
     teardownwindow = true;
     wait_for_thread(fDrawThreadID, &result);
     _FreeBuffers();
+       delete fSettings;
 }
 
 /*****************************************************************************
@@ -233,12 +318,12 @@ VideoWindow::MessageReceived( BMessage *p_message )
                case RESIZE_50:
                case RESIZE_100:
                case RESIZE_200:
-                       if (is_zoomed)
+                       if (IsFullScreen())
                                BWindow::Zoom();
                        _SetVideoSize(p_message->what);
                        break;
                case VERT_SYNC:
-                       vsync = !vsync;
+                       SetSyncToRetrace(!IsSyncedToRetrace());
                        break;
                case WINDOW_FEEL:
                        {
@@ -247,11 +332,15 @@ VideoWindow::MessageReceived( BMessage *p_message )
                                {
                                        SetFeel(winFeel);
                                        fCachedFeel = winFeel;
+                                       if (winFeel == B_FLOATING_ALL_WINDOW_FEEL)
+                                               fSettings->AddFlags(VideoSettings::FLAG_ON_TOP_ALL);
+                                       else
+                                               fSettings->ClearFlags(VideoSettings::FLAG_ON_TOP_ALL);
                                }
                        }
                        break;
                case ASPECT_CORRECT:
-                       SetCorrectAspectRatio(!fCorrectAspect);
+                       SetCorrectAspectRatio(!CorrectAspectRatio());
                        break;
                case SCREEN_SHOT:
                        // save a screen shot
@@ -299,24 +388,7 @@ VideoWindow::MessageReceived( BMessage *p_message )
 void
 VideoWindow::Zoom(BPoint origin, float width, float height )
 {
-       if(is_zoomed)
-       {
-               MoveTo(winSize.left, winSize.top);
-               ResizeTo(winSize.IntegerWidth(), winSize.IntegerHeight());
-               be_app->ShowCursor();
-               fInterfaceShowing = true;
-       }
-       else
-       {
-               BScreen screen(this);
-               BRect rect = screen.Frame();
-               Activate();
-               MoveTo(0.0, 0.0);
-               ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
-               be_app->ObscureCursor();
-               fInterfaceShowing = false;
-       }
-       is_zoomed = !is_zoomed;
+       ToggleFullScreen();
 }
 
 /*****************************************************************************
@@ -325,8 +397,9 @@ VideoWindow::Zoom(BPoint origin, float width, float height )
 void
 VideoWindow::FrameMoved(BPoint origin) 
 {
-       if (is_zoomed) return ;
-    winSize = Frame();
+       if (IsFullScreen())
+               return ;
+       winSize = Frame();
 }
 
 /*****************************************************************************
@@ -335,8 +408,8 @@ VideoWindow::FrameMoved(BPoint origin)
 void
 VideoWindow::FrameResized( float width, float height )
 {
-       int32 useWidth = fCorrectAspect ? i_width : fTrueWidth;
-       int32 useHeight = fCorrectAspect ? i_height : fTrueHeight;
+       int32 useWidth = CorrectAspectRatio() ? i_width : fTrueWidth;
+       int32 useHeight = CorrectAspectRatio() ? i_height : fTrueHeight;
     float out_width, out_height;
     float out_left, out_top;
     float width_scale = width / useWidth;
@@ -359,7 +432,7 @@ VideoWindow::FrameResized( float width, float height )
     view->MoveTo(out_left,out_top);
     view->ResizeTo(out_width, out_height);
 
-       if (!is_zoomed)
+       if (!IsFullScreen())
         winSize = Frame();
 }
 
@@ -374,8 +447,7 @@ VideoWindow::ScreenChanged(BRect frame, color_space format)
        screen.GetMode(&mode); 
        float refresh = (mode.timing.pixel_clock * 1000)
                                        / ((mode.timing.h_total) * (mode.timing.v_total)); 
-    if (refresh < MIN_AUTO_VSYNC_REFRESH) 
-        vsync = true; 
+       SetSyncToRetrace(refresh < MIN_AUTO_VSYNC_REFRESH);
 }
 
 /*****************************************************************************
@@ -395,7 +467,7 @@ VideoWindow::drawBuffer(int bufferIndex)
     i_buffer = bufferIndex;
 
     // sync to the screen if required
-    if (vsync)
+    if (IsSyncedToRetrace())
     {
         BScreen screen(this);
         screen.WaitForRetrace(22000);
@@ -464,13 +536,92 @@ VideoWindow::SetInterfaceShowing(bool showIt)
 void
 VideoWindow::SetCorrectAspectRatio(bool doIt)
 {
-       if (fCorrectAspect != doIt)
+       if (CorrectAspectRatio() != doIt)
        {
-               fCorrectAspect = doIt;
+               if (doIt)
+                       fSettings->AddFlags(VideoSettings::FLAG_CORRECT_RATIO);
+               else
+                       fSettings->ClearFlags(VideoSettings::FLAG_CORRECT_RATIO);
                FrameResized(Bounds().Width(), Bounds().Height());
        }
 }
 
+/*****************************************************************************
+ * VideoWindow::CorrectAspectRatio
+ *****************************************************************************/
+bool
+VideoWindow::CorrectAspectRatio() const
+{
+       return fSettings->HasFlags(VideoSettings::FLAG_CORRECT_RATIO);
+}
+
+/*****************************************************************************
+ * VideoWindow::ToggleFullScreen
+ *****************************************************************************/
+void
+VideoWindow::ToggleFullScreen()
+{
+       SetFullScreen(!IsFullScreen());
+}
+
+/*****************************************************************************
+ * VideoWindow::SetFullScreen
+ *****************************************************************************/
+void
+VideoWindow::SetFullScreen(bool doIt)
+{
+       if (doIt)
+       {
+               BScreen screen(this);
+               BRect rect = screen.Frame();
+               Activate();
+               MoveTo(0.0, 0.0);
+               ResizeTo(rect.IntegerWidth(), rect.IntegerHeight());
+               be_app->ObscureCursor();
+               fInterfaceShowing = false;
+               fSettings->AddFlags(VideoSettings::FLAG_FULL_SCREEN);
+       }
+       else
+       {
+               MoveTo(winSize.left, winSize.top);
+               ResizeTo(winSize.IntegerWidth(), winSize.IntegerHeight());
+               be_app->ShowCursor();
+               fInterfaceShowing = true;
+               fSettings->ClearFlags(VideoSettings::FLAG_FULL_SCREEN);
+       }
+}
+
+/*****************************************************************************
+ * VideoWindow::IsFullScreen
+ *****************************************************************************/
+bool
+VideoWindow::IsFullScreen() const
+{
+       return fSettings->HasFlags(VideoSettings::FLAG_FULL_SCREEN);
+}
+
+/*****************************************************************************
+ * VideoWindow::SetSyncToRetrace
+ *****************************************************************************/
+void
+VideoWindow::SetSyncToRetrace(bool doIt)
+{
+       if (doIt)
+               fSettings->AddFlags(VideoSettings::FLAG_SYNC_RETRACE);
+       else
+               fSettings->ClearFlags(VideoSettings::FLAG_SYNC_RETRACE);
+}
+
+/*****************************************************************************
+ * VideoWindow::IsSyncedToRetrace
+ *****************************************************************************/
+bool
+VideoWindow::IsSyncedToRetrace() const
+{
+       return fSettings->HasFlags(VideoSettings::FLAG_SYNC_RETRACE);
+}
+
+
 /*****************************************************************************
  * VideoWindow::_AllocateBuffers
  *****************************************************************************/
@@ -651,8 +802,8 @@ void
 VideoWindow::_SetVideoSize(uint32 mode)
 {
        // let size depend on aspect correction
-       int32 width = fCorrectAspect ? i_width : fTrueWidth;
-       int32 height = fCorrectAspect ? i_height : fTrueHeight;
+       int32 width = CorrectAspectRatio() ? i_width : fTrueWidth;
+       int32 height = CorrectAspectRatio() ? i_height : fTrueHeight;
        switch (mode)
        {
                case RESIZE_50:
@@ -667,8 +818,42 @@ VideoWindow::_SetVideoSize(uint32 mode)
                default:
                break;
        }
+       fSettings->ClearFlags(VideoSettings::FLAG_FULL_SCREEN);
        ResizeTo(width, height);
-       is_zoomed = false;
+}
+
+/*****************************************************************************
+ * VideoWindow::_SetToSettings
+ *****************************************************************************/
+void
+VideoWindow::_SetToSettings()
+{
+       // adjust dimensions
+       uint32 mode = RESIZE_100;
+       switch (fSettings->VideoSize())
+       {
+               case VideoSettings::SIZE_50:
+                       mode = RESIZE_50;
+                       break;
+               case VideoSettings::SIZE_200:
+                       mode = RESIZE_200;
+                       break;
+               case VideoSettings::SIZE_100:
+               case VideoSettings::SIZE_OTHER:
+               default:
+                       break;
+       }
+       bool fullscreen = IsFullScreen();       // remember settings
+       _SetVideoSize(mode);                            // because this will reset settings
+       // the fullscreen status is reflected in the settings,
+       // but not yet in the windows state
+       if (fullscreen)
+               SetFullScreen(true);
+       if (fSettings->HasFlags(VideoSettings::FLAG_ON_TOP_ALL))
+               fCachedFeel = B_FLOATING_ALL_WINDOW_FEEL;
+       else
+               fCachedFeel = B_NORMAL_WINDOW_FEEL;
+       SetFeel(fCachedFeel);
 }
 
 /*****************************************************************************
@@ -683,8 +868,8 @@ VideoWindow::_SaveScreenShot( BBitmap* bitmap, char* path,
        info->bitmap = bitmap;
        info->path = path;
        info->translatorID = translatorID;
-       info->width = fCorrectAspect ? i_width : fTrueWidth;
-       info->height = fCorrectAspect ? i_height : fTrueHeight;
+       info->width = CorrectAspectRatio() ? i_width : fTrueWidth;
+       info->height = CorrectAspectRatio() ? i_height : fTrueHeight;
        // spawn a new thread to take care of the actual saving to disk
        thread_id thread = spawn_thread( _save_screen_shot,
                                                                         "screen shot saver",
@@ -921,14 +1106,14 @@ VLCView::MouseDown(BPoint where)
                                menu->AddItem(doubleItem);
                                // Toggle FullScreen
                                BMenuItem *zoomItem = new BMenuItem("Fullscreen", new BMessage(TOGGLE_FULL_SCREEN));
-                               zoomItem->SetMarked(videoWindow->is_zoomed);
+                               zoomItem->SetMarked(videoWindow->IsFullScreen());
                                menu->AddItem(zoomItem);
        
                                menu->AddSeparatorItem();
        
                                // Toggle vSync
                                BMenuItem *vsyncItem = new BMenuItem("Vertical Sync", new BMessage(VERT_SYNC));
-                               vsyncItem->SetMarked(videoWindow->vsync);
+                               vsyncItem->SetMarked(videoWindow->IsSyncedToRetrace());
                                menu->AddItem(vsyncItem);
                                // Correct Aspect Ratio
                                BMenuItem *aspectItem = new BMenuItem("Correct Aspect Ratio", new BMessage(ASPECT_CORRECT));
@@ -1032,7 +1217,7 @@ VLCView::Pulse()
                        fCursorHidden = true;
                        VideoWindow *videoWindow = dynamic_cast<VideoWindow*>(Window());
                        // hide the interface window as well if full screen
-                       if (videoWindow && videoWindow->is_zoomed)
+                       if (videoWindow && videoWindow->IsFullScreen())
                                videoWindow->SetInterfaceShowing(false);
                }
        }
@@ -1057,7 +1242,7 @@ VLCView::KeyDown(const char *bytes, int32 numBytes)
                                break;
                        case B_ESCAPE:
                                // go back to window mode
-                               if (videoWindow->is_zoomed)
+                               if (videoWindow->IsFullScreen())
                                        videoWindow->PostMessage(TOGGLE_FULL_SCREEN);
                                break;
                        case B_SPACE:
index 775c04f..a9d185f 100644 (file)
@@ -2,7 +2,7 @@
  * VideoWindow.h: BeOS video window class prototype
  *****************************************************************************
  * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: VideoWindow.h,v 1.5 2002/12/07 22:00:36 titer Exp $
+ * $Id: VideoWindow.h,v 1.6 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Jean-Marc Dressler <polux@via.ecp.fr>
  *          Tony Castley <tcastley@mail.powerup.com.au>
@@ -55,6 +55,54 @@ colorcombo colspace[]=
 #define COLOR_COUNT 5
 #define DEFAULT_COL 3
 
+class VideoSettings
+{
+ public:
+                                                       VideoSettings( const VideoSettings& clone );
+       virtual                                 ~VideoSettings();
+
+       static  VideoSettings*  DefaultSettings();
+
+       enum
+       {
+               SIZE_OTHER                      = 0,
+               SIZE_50                         = 1,
+               SIZE_100                        = 2,
+               SIZE_200                        = 3,
+       };
+
+                       void                    SetVideoSize( uint32 mode );
+       inline  uint32                  VideoSize() const
+                                                               { return fVideoSize; }
+       enum
+       {
+               FLAG_CORRECT_RATIO      = 0x0001,
+               FLAG_SYNC_RETRACE       = 0x0002,
+               FLAG_ON_TOP_ALL         = 0x0004,
+               FLAG_FULL_SCREEN        = 0x0008,
+       };
+
+       inline  void                    SetFlags( uint32 flags )
+                                                               { fFlags = flags; }
+       inline  void                    AddFlags( uint32 flags )
+                                                               { fFlags |= flags; }
+       inline  void                    ClearFlags( uint32 flags )
+                                                               { fFlags &= ~flags; }
+       inline  bool                    HasFlags( uint32 flags ) const
+                                                               { return fFlags & flags; }
+       inline  uint32                  Flags() const
+                                                               { return fFlags; }
+
+ private:
+                                                       VideoSettings(); // reserved for default settings
+
+       static  VideoSettings   fDefaultSettings;
+
+                       uint32                  fVideoSize;
+                       uint32                  fFlags;
+                       BMessage*               fSettings;
+};
+
 
 class VLCView : public BView
 {
@@ -107,8 +155,14 @@ public:
                        void                    SetInterfaceShowing(bool showIt);
 
                        void                    SetCorrectAspectRatio(bool doIt);
-       inline  bool                    CorrectAspectRatio() const
-                                                               { return fCorrectAspect; }
+                       bool                    CorrectAspectRatio() const;
+                       void                    ToggleFullScreen();
+                       void                    SetFullScreen(bool doIt);
+                       bool                    IsFullScreen() const;
+                       void                    SetOnTop(bool doIt);
+                       bool                    IsOnTop() const;
+                       void                    SetSyncToRetrace(bool doIt);
+                       bool                    IsSyncedToRetrace() const;
        inline  status_t                InitCheck() const
                                                                { return fInitStatus; }
 
@@ -117,9 +171,8 @@ public:
     int32           i_width;     // aspect corrected bitmap size 
     int32           i_height;
     BRect           winSize;     // current window size
-    bool            is_zoomed, vsync;
     BBitmap            *bitmap[3];
-    BBitmap         *overlaybitmap;
+//    BBitmap         *overlaybitmap;
     VLCView            *view;
     int             i_buffer;
        volatile bool   teardownwindow;
@@ -134,6 +187,7 @@ private:
                        void                    _FreeBuffers();
                        void                    _BlankBitmap(BBitmap* bitmap) const;
                        void                    _SetVideoSize(uint32 mode);
+                       void                    _SetToSettings();
 
                        void                    _SaveScreenShot( BBitmap* bitmap,
                                                                                         char* path,
@@ -153,10 +207,10 @@ private:
 
        int32                   fTrueWidth;     // incomming bitmap size 
        int32                   fTrueHeight;
-       bool                    fCorrectAspect;
        window_feel             fCachedFeel;
        bool                    fInterfaceShowing;
        status_t                fInitStatus;
+       VideoSettings*  fSettings;
 };
 
 #endif // BEOS_VIDEO_WINDOW_H
index 29e87f7..0c5b2ca 100644 (file)
@@ -2,7 +2,7 @@
  * VlcWrapper.cpp: BeOS plugin for vlc (derived from MacOS X port)
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: VlcWrapper.cpp,v 1.23 2003/01/29 00:02:09 titer Exp $
+ * $Id: VlcWrapper.cpp,v 1.24 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Florian G. Pflug <fgp@phlo.org>
  *          Jon Lech Johansen <jon-vl@nanocrew.net>
@@ -358,35 +358,47 @@ bool VlcWrapper::IsPlaying()
  * playlist *
  ************/
 
-void VlcWrapper::OpenFiles( BList* o_files, bool replace )
+void VlcWrapper::OpenFiles( BList* o_files, bool replace, int32 index )
 {
-    BString *o_file;
-    int size = PlaylistSize();
-       bool wasEmpty = ( size < 1 );
-
-    /* delete current playlist */
-    if( replace )
-    {
-        for( int i = 0; i < size; i++ )
-        {
-            playlist_Delete( p_playlist, 0 );
-        }
-    }
-
-    /* append files */
-    while( ( o_file = (BString *)o_files->LastItem() ) )
-    {
-        playlist_Add( p_playlist, o_file->String(),
-                      PLAYLIST_APPEND, PLAYLIST_END );
-        o_files->RemoveItem(o_files->CountItems() - 1);
-    }
-    
-    /* eventually restart playing */
-    if( replace || wasEmpty )
-    {
-        playlist_Stop( p_playlist );
-        playlist_Play( p_playlist );
-    }
+       if ( o_files && o_files->CountItems() > 0)
+       {
+           int size = PlaylistSize();
+               bool wasEmpty = ( size < 1 );
+               if ( index == -1 )
+                       index = PLAYLIST_END;
+               int mode = index == PLAYLIST_END ? PLAYLIST_APPEND : PLAYLIST_INSERT;
+       
+           /* delete current playlist */
+           if( replace )
+           {
+               for( int i = 0; i < size; i++ )
+               {
+                   playlist_Delete( p_playlist, 0 );
+               }
+           }
+       
+           /* insert files */
+           int32 count = o_files->CountItems();
+           for ( int32 i = count - 1; i >= 0; i-- )
+           {
+               if ( BString* o_file = (BString *)o_files->RemoveItem( i ) )
+               {
+                       playlist_Add( p_playlist, o_file->String(),
+                                     mode, index );
+                       if ( mode == PLAYLIST_INSERT )
+                               index++;
+                       delete o_file;
+               }
+           }
+           // TODO: implement a user setting
+           // if to start automatically
+           /* eventually restart playing */
+           if( replace || wasEmpty )
+           {
+               playlist_Stop( p_playlist );
+               playlist_Play( p_playlist );
+           }
+       }
 }
  
 void VlcWrapper::OpenDisc(BString o_type, BString o_device, int i_title, int i_chapter)
@@ -455,11 +467,15 @@ void VlcWrapper::GetPlaylistInfo( int32& currentIndex, int32& maxIndex )
        maxIndex = -1;
        if ( p_playlist )
        {
+           vlc_mutex_lock( &p_playlist->object_lock );
+
                maxIndex = p_playlist->i_size;
                if ( maxIndex > 0 )
-                       currentIndex = p_playlist->i_index + 1;
+                       currentIndex = p_playlist->i_index/* + 1 -> why?!?*/;
                else
                        maxIndex = -1;
+
+           vlc_mutex_unlock( &p_playlist->object_lock );
        }
 }
 
@@ -611,6 +627,131 @@ void VlcWrapper::NavigateNext()
                PlaylistNext();
 }
 
+/*************************
+ * Playlist manipulation *
+ *************************/
+
+// PlaylistLock
+bool
+VlcWrapper::PlaylistLock() const
+{
+// TODO: search and destroy -> deadlock!
+return true;
+       if ( p_playlist )
+       {
+               vlc_mutex_lock( &p_playlist->object_lock );
+               return true;
+       }
+       return false;
+}
+
+// PlaylistUnlock
+void
+VlcWrapper::PlaylistUnlock() const
+{
+// TODO: search and destroy -> deadlock!
+return;
+       vlc_mutex_unlock( &p_playlist->object_lock );
+}
+
+// PlaylistItemAt
+void*
+VlcWrapper::PlaylistItemAt( int index ) const
+{
+       playlist_item_t* item = NULL;
+       if ( index >= 0 && index < p_playlist->i_size )
+               item = p_playlist->pp_items[index];
+       return (void*)item;
+}
+
+// PlaylistRemoveItem
+void*
+VlcWrapper::PlaylistRemoveItem( int index ) const
+{
+       playlist_item_t* copy = NULL;
+       // check if item exists at the provided index
+       if ( index >= 0 && index < p_playlist->i_size )
+       {
+               playlist_item_t* item = p_playlist->pp_items[index];
+               if ( item )
+               {
+                       // make a copy of the removed item
+                       copy = (playlist_item_t*)PlaylistCloneItem( (void*)item );
+                       // remove item from playlist (unfortunately, this frees it)
+                       playlist_Delete( p_playlist, index );
+               }
+       }
+       return (void*)copy;
+}
+
+// PlaylistRemoveItem
+void*
+VlcWrapper::PlaylistRemoveItem( void* item ) const
+{
+       playlist_item_t* copy = NULL;
+       for ( int32 i = 0; i < p_playlist->i_size; i++ )
+       {
+               if ( p_playlist->pp_items[i] == item )
+               {
+                       copy = (playlist_item_t*)PlaylistRemoveItem( i );
+                       break;
+               }
+       }
+       return (void*)copy;
+}
+
+// PlaylistAddItem
+bool
+VlcWrapper::PlaylistAddItem( void* item, int index ) const
+{
+       if ( item )
+       {
+               playlist_AddItem( p_playlist, (playlist_item_t*)item,
+                                                 PLAYLIST_INSERT, index );
+       }
+       // TODO: once playlist is returning useful info, return that instead
+       return true;
+}
+
+// PlaylistCloneItem
+void*
+VlcWrapper::PlaylistCloneItem( void* castToItem ) const
+{
+       playlist_item_t* copy = NULL;
+       playlist_item_t* item = (playlist_item_t*)castToItem;
+       if ( item )
+       {
+               copy = (playlist_item_t*)malloc( sizeof( playlist_item_t ) );
+               if ( copy )
+               {
+                       // make a copy of the item at index
+                       copy->psz_name = strdup( item->psz_name );
+                       copy->psz_uri  = strdup( item->psz_uri );
+                       copy->i_type = item->i_type;
+                       copy->i_status = item->i_status;
+                       copy->b_autodeletion = item->b_autodeletion;
+               }
+       }
+       return (void*)copy;
+}
+
+// Careful! You need to know what you're doing here!
+// The reason for having it, is to be able to deal with
+// the rather lame list implementation of the playlist.
+// It is meant to help manipulate the playlist with the above
+// methods while keeping it valid.
+//
+// PlaylistSetPlaying
+void
+VlcWrapper::PlaylistSetPlaying( int index ) const
+{
+       if ( index < 0 )
+               index = 0;
+       if ( index >= p_playlist->i_size )
+               index = p_playlist->i_size - 1;
+       p_playlist->i_index = index;
+}
+
 
 /*********
  * audio *
@@ -853,7 +994,7 @@ void VlcWrapper::ChapterInfo( int32 &currentIndex, int32 &maxIndex )
  * Miscellanous *
  ****************/
  
-void VlcWrapper::LoadSubFile( char * psz_file )
+void VlcWrapper::LoadSubFile( const char * psz_file )
 {
     config_PutPsz( p_intf, "sub-file", strdup( psz_file ) );
 }
index 4623ebb..c873b77 100644 (file)
@@ -2,7 +2,7 @@
  * VlcWrapper.h: BeOS plugin for vlc (derived from MacOS X port)
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: VlcWrapper.h,v 1.18 2003/01/29 00:02:09 titer Exp $
+ * $Id: VlcWrapper.h,v 1.19 2003/02/01 12:01:11 stippi Exp $
  *
  * Authors: Florian G. Pflug <fgp@phlo.org>
  *          Jon Lech Johansen <jon-vl@nanocrew.net>
@@ -79,7 +79,8 @@ public:
     bool         IsPlaying();
         
     /* Playlist */
-    void    OpenFiles( BList *o_files, bool replace = true );
+    void    OpenFiles( BList *o_files, bool replace = true,
+                                  int32 index = -1 );
     void    OpenDisc( BString o_type, BString o_device,
                      int i_title, int i_chapter );
     int     PlaylistSize();
@@ -99,6 +100,21 @@ public:
     void    NavigatePrev();
     void    NavigateNext();
 
+       /* Playlist manipulation */
+       bool    PlaylistLock() const;
+       void    PlaylistUnlock() const;
+       // playlist must be locked prior to calling all of these!
+       void*   PlaylistItemAt( int index ) const;
+                       // both functions return a copy of the removed item
+                       // so that it can be added at another index
+       void*   PlaylistRemoveItem( int index ) const;
+       void*   PlaylistRemoveItem( void* item ) const;
+                       // uses playlist_AddItem()
+       bool    PlaylistAddItem( void* item, int index ) const;
+       void*   PlaylistCloneItem( void* item ) const;
+                       // only modifies playlist, doesn't effect playback
+       void    PlaylistSetPlaying( int index ) const;
+
     /* Audio */
     bool           HasAudio();
     unsigned short GetVolume();
@@ -123,7 +139,7 @@ public:
     void    ChapterInfo( int32& currentIndex, int32& maxIndex );
     
     /* Miscellanous */
-    void LoadSubFile( char * psz_file );
+    void LoadSubFile( const char * psz_file );
     void FilterChange();
     
 private: