]> git.sesse.net Git - vlc/blobdiff - modules/gui/macosx/CoreInteraction.m
macosx: CAS: re-write the destination section's appearance to make it less cluttered
[vlc] / modules / gui / macosx / CoreInteraction.m
index 1fdeb1aee73935184e1fd2d77064e05cdea89d24..8a88e79bb109f7db07190b6eaf34f6b247cd7bb8 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * CoreInteraction.m: MacOS X interface module
  *****************************************************************************
- * Copyright (C) 2011 Felix Paul Kühne
+ * Copyright (C) 2011-2012 Felix Paul Kühne
  * $Id$
  *
  * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
 #import "CoreInteraction.h"
 #import "intf.h"
 #import "open.h"
+#import "playlist.h"
+#import <math.h>
 #import <vlc_playlist.h>
 #import <vlc_input.h>
 #import <vlc_keys.h>
 #import <vlc_osd.h>
 #import <vlc_aout_intf.h>
+#import <vlc/vlc.h>
+#import <vlc_strings.h>
+#import <vlc_url.h>
 
 @implementation VLCCoreInteraction
 static VLCCoreInteraction *_o_sharedInstance = nil;
@@ -43,7 +48,7 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
 
 - (id)init
 {
-    if( _o_sharedInstance)
+    if( _o_sharedInstance )
     {
         [self dealloc];
         return _o_sharedInstance;
@@ -51,9 +56,8 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
     else
     {
         _o_sharedInstance = [super init];
-        b_lockAspectRatio = YES;
     }
-    
+
     return _o_sharedInstance;
 }
 
@@ -65,7 +69,7 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
 
 - (void)awakeFromNib
 {
-    [[NSNotificationCenter defaultCenter] addObserver: self 
+    [[NSNotificationCenter defaultCenter] addObserver: self
                                              selector: @selector(applicationWillFinishLaunching:)
                                                  name: NSApplicationWillFinishLaunchingNotification
                                                object: nil];
@@ -78,17 +82,22 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
 {
     playlist_t * p_playlist = pl_Get( VLCIntf );
     bool empty;
-    
+
     PL_LOCK;
     empty = playlist_IsEmpty( p_playlist );
     PL_UNLOCK;
-    
+
     if( empty )
         [[[VLCMain sharedInstance] open] openFileGeneric];
-    
+
     var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE );
 }
 
+- (void)pause
+{
+    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_PAUSE );
+}
+
 - (void)stop
 {
     var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_STOP );
@@ -111,8 +120,12 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
 
 - (void)toggleRecord
 {
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return;
+
     input_thread_t * p_input;
-    p_input = pl_CurrentInput( VLCIntf );
+    p_input = pl_CurrentInput( p_intf );
     if( p_input )
     {
         var_ToggleBool( p_input, "record" );
@@ -133,10 +146,26 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
 
 - (int)playbackRate
 {
-    playlist_t * p_playlist = pl_Get( VLCIntf );
+    float f_rate;
+
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return 0;
+
+    input_thread_t * p_input;
+    p_input = pl_CurrentInput( p_intf );
+    if( p_input )
+    {
+        f_rate = var_GetFloat( p_input, "rate" );
+        vlc_object_release( p_input );
+    }
+    else
+    {
+        playlist_t * p_playlist = pl_Get( VLCIntf );
+        f_rate = var_GetFloat( p_playlist, "rate" );
+    }
 
-    float rate = var_GetFloat( p_playlist, "rate" );
-    double value = 17 * log( rate ) / log( 2. );
+    double value = 17 * log( f_rate ) / log( 2. );
     int returnValue = (int) ( ( value > 0 ) ? value + .5 : value - .5 );
 
     if( returnValue < -34 )
@@ -158,20 +187,202 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
     var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_NEXT );
 }
 
+- (BOOL)isPlaying
+{
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return NO;
+
+    input_thread_t * p_input = pl_CurrentInput( p_intf );
+    if( !p_input )
+        return NO;
+
+    input_state_e i_state = ERROR_S;
+    input_Control( p_input, INPUT_GET_STATE, &i_state );
+    vlc_object_release( p_input );
+
+    return ( ( i_state == OPENING_S ) || ( i_state == PLAYING_S ) );
+}
+
+- (int)currentTime
+{
+    input_thread_t * p_input = pl_CurrentInput( VLCIntf );
+    int64_t i_currentTime = -1;
+
+    if( !p_input )
+        return i_currentTime;
+
+    input_Control( p_input, INPUT_GET_TIME, &i_currentTime );
+    vlc_object_release( p_input );
+
+    return (int)( i_currentTime / 1000000 );
+}
+
+- (void)setCurrentTime:(int)i_value
+{
+    int64_t i64_value = (int64_t)i_value;
+    input_thread_t * p_input = pl_CurrentInput( VLCIntf );
+
+    if ( !p_input )
+        return;
+
+    input_Control( p_input, INPUT_SET_TIME, (int64_t)(i64_value * 1000000) );
+    vlc_object_release( p_input );
+}
+
+- (int)durationOfCurrentPlaylistItem
+{
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return 0;
+
+    input_thread_t * p_input = pl_CurrentInput( p_intf );
+    int64_t i_duration = -1;
+    if( !p_input )
+        return i_duration;
+
+    input_Control( p_input, INPUT_GET_LENGTH, &i_duration );
+    vlc_object_release( p_input );
+
+    return (int)( i_duration / 1000000 );
+}
+
+- (NSURL*)URLOfCurrentPlaylistItem
+{
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return nil;
+
+    input_thread_t *p_input = pl_CurrentInput( p_intf );
+    if( !p_input )
+        return nil;
+
+    input_item_t *p_item = input_GetItem( p_input );
+    if( !p_item )
+    {
+        vlc_object_release( p_input );
+        return nil;
+    }
+
+    char *psz_uri = input_item_GetURI( p_item );
+    if( !psz_uri )
+    {
+        vlc_object_release( p_input );
+        return nil;
+    }
+
+    NSURL *o_url;
+    o_url = [NSURL URLWithString:[NSString stringWithUTF8String:psz_uri]];
+    vlc_object_release( p_input );
+
+    return o_url;
+}
+
+- (NSString*)nameOfCurrentPlaylistItem
+{
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return nil;
+
+    input_thread_t *p_input = pl_CurrentInput( p_intf );
+    if( !p_input )
+        return nil;
+
+    input_item_t *p_item = input_GetItem( p_input );
+    if( !p_item )
+    {
+        vlc_object_release( p_input );
+        return nil;
+    }
+
+    char *psz_uri = input_item_GetURI( p_item );
+    if( !psz_uri )
+    {
+        vlc_object_release( p_input );
+        return nil;
+    }
+
+    NSString *o_name;
+    char *format = var_InheritString( VLCIntf, "input-title-format" );
+    char *formated = str_format_meta( p_input, format );
+    free( format );
+    o_name = [NSString stringWithUTF8String:formated];
+    free( formated );
+
+    NSURL * o_url = [NSURL URLWithString: [NSString stringWithUTF8String: psz_uri]];
+    free( psz_uri );
+
+    if( [o_name isEqualToString:@""] )
+    {
+        if( [o_url isFileURL] )
+            o_name = [[NSFileManager defaultManager] displayNameAtPath: [o_url path]];
+        else
+            o_name = [o_url absoluteString];
+    }
+    vlc_object_release( p_input );
+    return o_name;
+}
+
 - (void)forward
 {
-    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_SHORT );
+    //LEGACY SUPPORT
+    [self forwardShort];
 }
 
 - (void)backward
+{
+    //LEGACY SUPPORT
+    [self backwardShort];
+}
+
+- (void)forwardExtraShort
+{
+    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_EXTRASHORT );
+}
+
+- (void)backwardExtraShort
+{
+    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_EXTRASHORT );
+}
+
+- (void)forwardShort
+{
+    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_SHORT );
+}
+
+- (void)backwardShort
 {
     var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_SHORT );
 }
 
+- (void)forwardMedium
+{
+    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_MEDIUM );
+}
+
+- (void)backwardMedium
+{
+    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_MEDIUM );
+}
+
+- (void)forwardLong
+{
+    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_LONG );
+}
+
+- (void)backwardLong
+{
+    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_LONG );
+}
+
 - (void)shuffle
 {
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return;
+
     vlc_value_t val;
-    playlist_t * p_playlist = pl_Get( VLCIntf );
+    playlist_t * p_playlist = pl_Get( p_intf );
     vout_thread_t *p_vout = getVout();
 
     var_Get( p_playlist, "random", &val );
@@ -179,7 +390,7 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
     var_Set( p_playlist, "random", val );
     if( val.b_bool )
     {
-        if (p_vout)
+        if( p_vout )
         {
             vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Random On" ) );
             vlc_object_release( p_vout );
@@ -188,7 +399,7 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
     }
     else
     {
-        if (p_vout)
+        if( p_vout )
         {
             vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Random Off" ) );
             vlc_object_release( p_vout );
@@ -199,7 +410,11 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
 
 - (void)repeatAll
 {
-    playlist_t * p_playlist = pl_Get( VLCIntf );
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return;
+
+    playlist_t * p_playlist = pl_Get( p_intf );
 
     var_SetBool( p_playlist, "repeat", NO );
     var_SetBool( p_playlist, "loop", YES );
@@ -207,7 +422,7 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
     config_PutInt( p_playlist, "loop", YES );
 
     vout_thread_t *p_vout = getVout();
-    if (p_vout)
+    if( p_vout )
     {
         vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat All" ) );
         vlc_object_release( p_vout );
@@ -216,7 +431,11 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
 
 - (void)repeatOne
 {
-    playlist_t * p_playlist = pl_Get( VLCIntf );
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return;
+
+    playlist_t * p_playlist = pl_Get( p_intf );
 
     var_SetBool( p_playlist, "repeat", YES );
     var_SetBool( p_playlist, "loop", NO );
@@ -224,7 +443,7 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
     config_PutInt( p_playlist, "loop", NO );
 
     vout_thread_t *p_vout = getVout();
-    if (p_vout)
+    if( p_vout )
     {
         vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat One" ) );
         vlc_object_release( p_vout );
@@ -233,7 +452,11 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
 
 - (void)repeatOff
 {
-    playlist_t * p_playlist = pl_Get( VLCIntf );
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return;
+
+    playlist_t * p_playlist = pl_Get( p_intf );
 
     var_SetBool( p_playlist, "repeat", NO );
     var_SetBool( p_playlist, "loop", NO );
@@ -241,7 +464,7 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
     config_PutInt( p_playlist, "loop", NO );
 
     vout_thread_t *p_vout = getVout();
-    if (p_vout)
+    if( p_vout )
     {
         vout_OSDMessage( p_vout, SPU_DEFAULT_CHANNEL, "%s", _( "Repeat Off" ) );
         vlc_object_release( p_vout );
@@ -250,28 +473,115 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
 
 - (void)volumeUp
 {
-    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_VOL_UP );
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return;
+
+    aout_VolumeUp( pl_Get( p_intf ), 1, NULL );
 }
 
 - (void)volumeDown
 {
-    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_VOL_DOWN );
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return;
+
+    aout_VolumeDown( pl_Get( p_intf ), 1, NULL );
 }
 
 - (void)mute
 {
-    var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_VOL_MUTE );
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return;
+
+    aout_MuteToggle( pl_Get( p_intf ) );
+}
+
+- (BOOL)isMuted
+{
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return NO;
+
+    BOOL b_is_muted = NO;
+    b_is_muted = aout_MuteGet( pl_Get( p_intf ) ) > 0;
+
+    return b_is_muted;
+}
+
+- (int)volume
+{
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return 0;
+
+    float volume = aout_VolumeGet( pl_Get( p_intf ) );
+
+    return lroundf(volume * AOUT_VOLUME_DEFAULT);
 }
 
 - (void)setVolume: (int)i_value
 {
-    intf_thread_t * p_intf = VLCIntf;
-    playlist_t * p_playlist = pl_Get( VLCIntf );
-    audio_volume_t i_volume = (audio_volume_t)i_value;
-    int i_volume_step;
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return;
 
-    i_volume_step = config_GetInt( VLCIntf->p_libvlc, "volume-step" );
-    aout_VolumeSet( p_playlist, i_volume * i_volume_step );
+    aout_VolumeSet( pl_Get( p_intf ), i_value / (float)AOUT_VOLUME_DEFAULT );
+}
+
+#pragma mark -
+#pragma mark drag and drop support for VLCVoutView, VLBrushedMetalImageView and VLCThreePartDropView
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+    NSPasteboard *o_paste = [sender draggingPasteboard];
+    NSArray *o_types = [NSArray arrayWithObject: NSFilenamesPboardType];
+    NSString *o_desired_type = [o_paste availableTypeFromArray:o_types];
+    NSData *o_carried_data = [o_paste dataForType:o_desired_type];
+    BOOL b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
+
+    if( o_carried_data )
+    {
+        if( [o_desired_type isEqualToString:NSFilenamesPboardType] )
+        {
+            NSArray *o_array = [NSArray array];
+            NSArray *o_values = [[o_paste propertyListForType: NSFilenamesPboardType] sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
+            NSUInteger count = [o_values count];
+
+            input_thread_t * p_input = pl_CurrentInput( VLCIntf );
+            BOOL b_returned = NO;
+
+            if( count == 1 && p_input )
+            {
+                b_returned = input_AddSubtitle( p_input, make_URI([[o_values objectAtIndex:0] UTF8String], NULL), true );
+                vlc_object_release( p_input );
+                if( !b_returned )
+                    return YES;
+            }
+            else if( p_input )
+                vlc_object_release( p_input );
+
+            for( NSUInteger i = 0; i < count; i++)
+            {
+                NSDictionary *o_dic;
+                char *psz_uri = make_URI([[o_values objectAtIndex:i] UTF8String], NULL);
+                if( !psz_uri )
+                    continue;
+
+                o_dic = [NSDictionary dictionaryWithObject:[NSString stringWithCString:psz_uri encoding:NSUTF8StringEncoding] forKey:@"ITEM_URL"];
+                free( psz_uri );
+
+                o_array = [o_array arrayByAddingObject: o_dic];
+            }
+            if( b_autoplay )
+                [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:NO];
+            else
+                [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:YES];
+
+            return YES;
+        }
+    }
+    return NO;
 }
 
 #pragma mark -
@@ -279,17 +589,65 @@ static VLCCoreInteraction *_o_sharedInstance = nil;
 
 - (void)setAspectRatioLocked:(BOOL)b_value
 {
-    b_lockAspectRatio = b_value;
+    config_PutInt( VLCIntf, "macosx-lock-aspect-ratio", b_value );
 }
 
 - (BOOL)aspectRatioIsLocked
 {
-    return b_lockAspectRatio;
+    return config_GetInt( VLCIntf, "macosx-lock-aspect-ratio" );
 }
 
 - (void)toggleFullscreen
 {
-    playlist_t * p_playlist = pl_Get( VLCIntf );
-    var_ToggleBool( p_playlist, "fullscreen" );
+    intf_thread_t *p_intf = VLCIntf;
+    if( !p_intf )
+        return;
+
+    BOOL b_fs = var_ToggleBool( pl_Get( p_intf ), "fullscreen" );
+
+    vout_thread_t *p_vout = getVout();
+    if( p_vout )
+    {
+        var_SetBool( p_vout, "fullscreen", b_fs );
+        vlc_object_release( p_vout );
+    }
+}
+
+#pragma mark -
+#pragma mark uncommon stuff
+
+- (BOOL)fixPreferences
+{
+    NSMutableString * o_workString;
+    NSRange returnedRange;
+    NSRange fullRange;
+    BOOL b_needsRestart = NO;
+
+    #define fixpref( pref ) \
+    o_workString = [[NSMutableString alloc] initWithFormat:@"%s", config_GetPsz( VLCIntf, pref )]; \
+    if ([o_workString length] > 0) \
+    { \
+        returnedRange = [o_workString rangeOfString:@"macosx" options: NSCaseInsensitiveSearch]; \
+        if (returnedRange.location != NSNotFound) \
+        { \
+            if ([o_workString isEqualToString:@"macosx"]) \
+                [o_workString setString:@""]; \
+            fullRange = NSMakeRange( 0, [o_workString length] ); \
+            [o_workString replaceOccurrencesOfString:@":macosx" withString:@"" options: NSCaseInsensitiveSearch range: fullRange]; \
+            fullRange = NSMakeRange( 0, [o_workString length] ); \
+            [o_workString replaceOccurrencesOfString:@"macosx:" withString:@"" options: NSCaseInsensitiveSearch range: fullRange]; \
+            \
+            config_PutPsz( VLCIntf, pref, [o_workString UTF8String] ); \
+            b_needsRestart = YES; \
+        } \
+    } \
+    [o_workString release]
+
+    fixpref( "control" );
+    fixpref( "extraintf" );
+    #undef fixpref
+
+    return b_needsRestart;
 }
+
 @end