/* * PlayerCtrllr.m * MPlayer OS X * * Created by Jan Volf * * Copyright (c) 2003 Jan Volf. All rights reserved. */ #import "PlayerCtrllr.h" // other conreollers #import "AppController.h" #import "PlayListCtrllr.h" // custom classes #import "ScrubbingBar.h" @implementation PlayerCtrllr /************************************************************************************/ -(void)awakeFromNib { NSUserDefaults *prefs = [appController preferences]; unichar myChar; saveTime = YES; fullscreenStatus = NO; // by default we play in window // init player myPlayer = [[MplayerInterface alloc] initWithPathToPlayer: [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"mplayer.app/Contents/MacOS/mplayer"]]; /* myPlayer = [[MplayerInterface alloc] initWithPathToPlayer: [[NSBundle mainBundle] pathForResource:@"mplayer" ofType:nil]]; */ // register for mplayer playback start [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(playbackStarted) name: @"MIInfoReadyNotification" object:myPlayer]; // register for mplayer status update [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(statusUpdate:) name: @"MIStateUpdatedNotification" object:myPlayer]; // register for notification on clicking progress bar [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(progresBarClicked:) name: @"SBBarClickedNotification" object:progressBar]; // register for app launch finish [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appFinishedLaunching) name: NSApplicationDidFinishLaunchingNotification object:NSApp]; // register for app termination notification [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appTerminating) name: NSApplicationWillTerminateNotification object:NSApp]; // register for app pre termination notification [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(appShouldTerminate) name: @"ApplicationShouldTerminateNotification" object:NSApp]; // load images playImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"play" ofType:@"png"]]; pauseImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"pause" ofType:@"png"]]; // load mini images playImageMini = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"play_mini" ofType:@"png"]]; pauseImageMini = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"pause_mini" ofType:@"png"]]; // set up prograss bar #ifdef __COCOA__ [progressBar setStyle:NSScrubbingBarEmptyStyle]; #endif [progressBar setIndeterminate:NO]; // set up controls key equivalents [playMenuItem setKeyEquivalent:@"space"]; myChar = NSLeftArrowFunctionKey; [seekBackMenuItem setKeyEquivalent: [NSString stringWithCharacters:(const unichar *) &myChar length:1]]; [seekBackMenuItem setKeyEquivalentModifierMask:0]; myChar = NSRightArrowFunctionKey; [seekFwdMenuItem setKeyEquivalent: [NSString stringWithCharacters:(const unichar *) &myChar length:1]]; [seekFwdMenuItem setKeyEquivalentModifierMask:0]; // set volume to the last used value if ([prefs objectForKey:@"LastAudioVolume"]) { [volumeSlider setDoubleValue:[[prefs objectForKey:@"LastAudioVolume"] doubleValue]]; [volumeSliderMini setDoubleValue:[[prefs objectForKey:@"LastAudioVolume"] doubleValue]]; [myPlayer setVolume:[[prefs objectForKey:@"LastAudioVolume"] intValue]]; } else { [volumeSlider setDoubleValue:100]; [volumeSliderMini setDoubleValue:100]; [myPlayer setVolume:100]; } // display player window if ([prefs objectForKey:@"MinimizedWindow"]) { if ([[prefs objectForKey:@"MinimizedWindow"] isEqualToString:@"YES"]) [self displayWindow:YES]; else [self displayWindow:NO]; } else [self displayWindow:NO]; // apply prefs to player [self applyPrefs]; } /************************************************************************************ INTERFACE ************************************************************************************/ - (void) displayWindow: (BOOL)minimized { if (minimized) { [miniWindow makeKeyAndOrderFront:nil]; } else { [mainWindow makeKeyAndOrderFront:nil]; } } /************************************************************************************/ - (BOOL)preflightItem:(NSMutableDictionary *)anItem { BOOL result; MplayerInterface *preflightTask = [MplayerInterface alloc]; NSDictionary *theInfo; // init preflight task with path to player [preflightTask initWithPathToPlayer:[[NSBundle mainBundle] pathForResource:@"preflighter" ofType:@""]]; // set movie [preflightTask setMovieFile:[anItem objectForKey:@"MovieFile"]]; // perform preflight theInfo = [preflightTask loadInfo]; if (theInfo) { [anItem addEntriesFromDictionary:theInfo]; result = YES; } else result = NO; // release the task [preflightTask autorelease]; return result; } /************************************************************************************/ - (void)playItem:(NSMutableDictionary *)anItem { NSString *aPath; BOOL loadInfo; // stops mplayer if it is running if ([myPlayer isRunning]) { saveTime = NO; // don't save time [myPlayer stop]; [playListController updateView]; } // prepare player // set movie file aPath = [anItem objectForKey:@"MovieFile"]; if (aPath) { if ([[NSFileManager defaultManager] fileExistsAtPath:aPath] || [NSURL URLWithString:aPath]) // if the file exist or it is an URL [myPlayer setMovieFile:aPath]; else { NSRunAlertPanel(NSLocalizedString(@"Error",nil), [NSString stringWithFormat: NSLocalizedString(@"File %@ could not be found.",nil), aPath], NSLocalizedString(@"OK",nil),nil,nil); return; } } else return; // backup item that is playing myPlayingItem = [anItem retain]; // apply item settings [self applySettings]; // if monitors aspect ratio is not 4:3 set monitor aspect ratio to the real one if ([[NSScreen mainScreen] frame].size.width/4 != [[NSScreen mainScreen] frame].size.height/3) { [myPlayer setMonitorAspectRatio:([[NSScreen mainScreen] frame].size.width / [[NSScreen mainScreen] frame].size.height)]; } // set video size for case it is set to fit screen so we have to compare // screen size with movie size [self setMovieSize]; // set the start of playback if ([myPlayingItem objectForKey:@"LastSeconds"]) [myPlayer seek:[[myPlayingItem objectForKey:@"LastSeconds"] floatValue] mode:MIAbsoluteSeekingMode]; else [myPlayer seek:0 mode:MIAbsoluteSeekingMode]; if (myPlayingItem) [myPlayingItem removeObjectForKey:@"LastSeconds"]; // load info before playback only if it was not previously loaded if ([myPlayingItem objectForKey:@"ID_FILENAME"]) loadInfo = NO; else loadInfo = YES; [myPlayer loadInfoBeforePlayback:loadInfo]; // start playback [myPlayer play]; // its enough to load info only once so disable it if (loadInfo) [myPlayer loadInfoBeforePlayback:NO]; } /************************************************************************************/ - (NSMutableDictionary *) playingItem { if ([myPlayer isRunning]) return [[myPlayingItem retain] autorelease]; // get it's own retention else return nil; } /************************************************************************************/ - (BOOL) isRunning { return [myPlayer isRunning]; } /************************************************************************************/ - (BOOL) isPlaying { if ([myPlayer status] != kStopped && [myPlayer status] != kFinished) return YES; else return NO; } /************************************************************************************/ // applay values from preferences to player controller - (void) applyPrefs; { NSUserDefaults *preferences = [appController preferences]; if ([preferences objectForKey:@"SubtitlesFontPath"]) { // if subtitles font is specified // set the font [myPlayer setFontFile:[[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Fonts"] stringByAppendingPathComponent:[preferences objectForKey:@"SubtitlesFontPath"]]]; if ([[[preferences objectForKey:@"SubtitlesFontPath"] lastPathComponent] caseInsensitiveCompare:@"font.desc"] == NSOrderedSame) { // if prerendered font selected [myPlayer setSubtitlesScale:0]; } else { // if true type font selected // set subtitles size if ([preferences objectForKey:@"SubtitlesSize"]) { switch ([[preferences objectForKey:@"SubtitlesSize"] intValue]) { case 0 : // smaller [myPlayer setSubtitlesScale:3]; break; case 1 : // normal [myPlayer setSubtitlesScale:4]; break; case 2 : // larger [myPlayer setSubtitlesScale:5]; break; case 3 : // largest [myPlayer setSubtitlesScale:7]; break; default : [myPlayer setSubtitlesScale:0]; break; } } } } else { // if ther's no subtitles font [myPlayer setFontFile:nil]; [myPlayer setSubtitlesScale:0]; } // set encoding [self setSubtitlesEncoding]; // set video size [self setMovieSize]; // set aspect ratio if ([preferences objectForKey:@"VideoAspectRatio"]) { switch ([[preferences objectForKey:@"VideoAspectRatio"] intValue]) { case 1 : [myPlayer setAspectRatio:1.3333]; // 4:3 break; case 2 : [myPlayer setAspectRatio:1.7777]; // 16:9 break; default : [myPlayer setAspectRatio:0]; break; } } else [myPlayer setAspectRatio:0]; // default fullscreen if ([preferences objectForKey:@"FullscreenByDefault"]) { if ([[preferences objectForKey:@"FullscreenByDefault"] isEqualToString:@"YES"]) [myPlayer setFullscreen:YES]; else [myPlayer setFullscreen:NO]; } else [myPlayer setFullscreen:NO]; ////BETA CODE//// // rootwin if ([preferences objectForKey:@"Rootwin"]) { if ([[preferences objectForKey:@"Rootwin"] isEqualToString:@"YES"]) [myPlayer setRootwin:YES]; else [myPlayer setRootwin:NO]; } else [myPlayer setRootwin:NO]; // tile if ([preferences objectForKey:@"Tile"]) { if ([[preferences objectForKey:@"Tile"] isEqualToString:@"YES"]) [myPlayer setTile:YES]; else [myPlayer setTile:NO]; } else [myPlayer setTile:NO]; //nosund if ([preferences objectForKey:@"nosound"]) { if ([[preferences objectForKey:@"nosound"] isEqualToString:@"YES"]) [myPlayer setnosound:YES]; else [myPlayer setnosound:NO]; } else [myPlayer setnosound:NO]; //secondmonitor if ([preferences objectForKey:@"SecondMonitor"]) { if ([[preferences objectForKey:@"SecondMonitor"] isEqualToString:@"YES"]) [myPlayer setSecondMonitor:YES]; else [myPlayer setSecondMonitor:NO]; } else [myPlayer setSecondMonitor:NO]; //postprocesing if ([preferences objectForKey:@"Postprocesing"]) { if ([[preferences objectForKey:@"Postprocesing"] isEqualToString:@"YES"]) [myPlayer setPostprocesing:YES]; else [myPlayer setPostprocesing:NO]; } else [myPlayer setPostprocesing:NO]; // drop frames if ([preferences objectForKey:@"DropFrames"]) { if ([[preferences objectForKey:@"DropFrames"] isEqualToString:@"YES"]) [myPlayer setDropFrames:YES]; else [myPlayer setDropFrames:NO]; } else [myPlayer setDropFrames:NO]; // setting cache if ([preferences objectForKey:@"CacheSize"]) { [myPlayer setCacheSize: ([[preferences objectForKey:@"CacheSize"] unsignedIntValue] * 1024)]; } // additional params if ([preferences objectForKey:@"EnableAdditionalParams"]) if ([[preferences objectForKey:@"EnableAdditionalParams"] isEqualToString:@"YES"] && [preferences objectForKey:@"AdditionalParams"]) { [myPlayer setAdditionalParams: [[[preferences objectForKey:@"AdditionalParams"] objectAtIndex:0] componentsSeparatedByString:@" "]]; } else [myPlayer setAdditionalParams:nil]; else [myPlayer setAdditionalParams:nil]; } /************************************************************************************/ - (void) applySettings { NSString *aPath; // set audio file aPath = [myPlayingItem objectForKey:@"AudioFile"]; if (aPath) { if (![[NSFileManager defaultManager] fileExistsAtPath:aPath]) NSRunAlertPanel(NSLocalizedString(@"Error",nil), [NSString stringWithFormat: NSLocalizedString(@"File %@ could not be found.",nil), aPath], NSLocalizedString(@"OK",nil),nil,nil); else [myPlayer setAudioFile:aPath]; } else [myPlayer setAudioFile:nil]; // // set audioexport BETA // aPath = [myPlayingItem objectForKey:@"AudioExportFile"]; // if (aPath) { // if (![[NSFileManager defaultManager] fileExistsAtPath:aPath]) // NSRunAlertPanel(NSLocalizedString(@"Error",nil), [NSString stringWithFormat: // NSLocalizedString(@"Audio file saving enabled",nil), aPath], // NSLocalizedString(@"OK",nil),nil,nil); // else // [myPlayer setAudioExportFile:nil]; // } // else // [myPlayer setAudioExportFile:nil]; // set subtitles file aPath = [myPlayingItem objectForKey:@"SubtitlesFile"]; if (aPath) { if (![[NSFileManager defaultManager] fileExistsAtPath:aPath]) NSRunAlertPanel(NSLocalizedString(@"Error",nil), [NSString stringWithFormat: NSLocalizedString(@"File %@ could not be found.",nil), aPath], NSLocalizedString(@"OK",nil),nil,nil); else [myPlayer setSubtitlesFile:aPath]; } else [myPlayer setSubtitlesFile:nil]; // set to rebuild index if ([myPlayingItem objectForKey:@"RebuildIndex"]) { if ([[myPlayingItem objectForKey:@"RebuildIndex"] isEqualToString:@"YES"]) [myPlayer setRebuildIndex:YES]; else [myPlayer setRebuildIndex:NO]; } else [myPlayer setRebuildIndex:NO]; // set subtitles encoding only if not default if ([myPlayingItem objectForKey:@"SubtitlesEncoding"]) [self setSubtitlesEncoding]; else [myPlayer setSubtitlesEncoding:nil]; // set status box if ([myPlayingItem objectForKey:@"ItemTitle"]) { [titleBox setStringValue:[myPlayingItem objectForKey:@"ItemTitle"]]; [titleBoxMini setStringValue:[myPlayingItem objectForKey:@"ItemTitle"]]; } else { [titleBox setStringValue:[[myPlayingItem objectForKey:@"MovieFile"] lastPathComponent]]; [titleBoxMini setStringValue:[[myPlayingItem objectForKey:@"MovieFile"] lastPathComponent]]; } } /************************************************************************************/ - (BOOL) changesRequireRestart { if ([myPlayer isRunning]) return [myPlayer changesNeedsRestart]; return NO; } /************************************************************************************/ - (void) applyChangesWithRestart:(BOOL)restart { [myPlayer applySettingsWithRestart:restart]; } /************************************************************************************ MISC ************************************************************************************/ - (void) setMovieSize { NSUserDefaults *preferences = [appController preferences]; if ([preferences objectForKey:@"VideoFrameSize"]) { switch ([[preferences objectForKey:@"VideoFrameSize"] intValue]) { case 0 : // normal [myPlayer setMovieSize:kDefaultMovieSize]; break; case 1 : // half [myPlayer setMovieSize:NSMakeSize(0.5, 0)]; break; case 2 : // double [myPlayer setMovieSize:NSMakeSize(2, 0)]; break; case 3 : // fit screen it (it is set before actual playback) if ([myPlayingItem objectForKey:@"ID_VIDEO_WIDTH"] && [myPlayingItem objectForKey:@"ID_VIDEO_HEIGHT"]) { NSSize screenSize = [[NSScreen mainScreen] visibleFrame].size; double theWidth = ((screenSize.height - 28) / // 28 pixels for window caption [[myPlayingItem objectForKey:@"ID_VIDEO_HEIGHT"] intValue] * [[myPlayingItem objectForKey:@"ID_VIDEO_WIDTH"] intValue]); if (theWidth < screenSize.width) [myPlayer setMovieSize:NSMakeSize(theWidth, 0)]; else [myPlayer setMovieSize:NSMakeSize(screenSize.width, 0)]; } break; case 4 : // fit width if ([preferences objectForKey:@"VideoFrameWidth"]) [myPlayer setMovieSize:NSMakeSize([[preferences objectForKey:@"VideoFrameWidth"] unsignedIntValue], 0)]; else [myPlayer setMovieSize:kDefaultMovieSize]; break; default : [myPlayer setMovieSize:kDefaultMovieSize]; break; } } else [myPlayer setMovieSize:kDefaultMovieSize]; } /************************************************************************************/ - (void) setSubtitlesEncoding { NSUserDefaults *preferences = [appController preferences]; if ([preferences objectForKey:@"SubtitlesFontPath"]) { if ([[[preferences objectForKey:@"SubtitlesFontPath"] lastPathComponent] caseInsensitiveCompare:@"font.desc"] != NSOrderedSame) { // if font is not a font.desc font then set subtitles encoding if (myPlayingItem) { if ([myPlayingItem objectForKey:@"SubtitlesEncoding"]) [myPlayer setSubtitlesEncoding:[myPlayingItem objectForKey:@"SubtitlesEncoding"]]; else [myPlayer setSubtitlesEncoding: [preferences objectForKey:@"SubtitlesEncoding"]]; } else [myPlayer setSubtitlesEncoding: [preferences objectForKey:@"SubtitlesEncoding"]]; } else [myPlayer setSubtitlesEncoding:nil]; } } /************************************************************************************ ACTIONS ************************************************************************************/ - (IBAction)changeVolume:(id)sender { [[appController preferences] setObject:[NSNumber numberWithDouble:[sender doubleValue]] forKey:@"LastAudioVolume"]; if (sender == volumeSlider) [volumeSliderMini setDoubleValue:[sender doubleValue]]; else [volumeSlider setDoubleValue:[sender doubleValue]]; [myPlayer setVolume:[sender intValue]]; [myPlayer applySettingsWithRestart:NO]; } /************************************************************************************/ - (IBAction)playPause:(id)sender { if ([myPlayer status] > 0) { [myPlayer pause]; // if playing pause/unpause } else { // set the item to play if ([playListController indexOfSelectedItem] < 0) [playListController selectItemAtIndex:0]; // if it is not set in the prefs by default play in window if ([[appController preferences] objectForKey:@"FullscreenByDefault"]) { if (![[[appController preferences] objectForKey:@"FullscreenByDefault"] isEqualToString:@"YES"]) [myPlayer setFullscreen:NO]; } // play the item [self playItem:[playListController selectedItem]]; } [playListController updateView]; } /************************************************************************************/ - (IBAction)seekBack:(id)sender { if ([myPlayer isRunning]) [myPlayer seek:-10 mode:MIRelativeSeekingMode]; else { if ([playListController indexOfSelectedItem] < 1) [playListController selectItemAtIndex:0]; else [playListController selectItemAtIndex: ([playListController indexOfSelectedItem]-1)]; } [playListController updateView]; } /************************************************************************************/ - (IBAction)seekFwd:(id)sender { if ([myPlayer isRunning]) [myPlayer seek:10 mode:MIRelativeSeekingMode]; else { if ([playListController indexOfSelectedItem] < ([playListController itemCount]-1)) [playListController selectItemAtIndex: ([playListController indexOfSelectedItem]+1)]; else [playListController selectItemAtIndex:([playListController itemCount]-1)]; } [playListController updateView]; } /************************************************************************************/ - (IBAction)stop:(id)sender { saveTime = NO; // if user stops player, don't save time [myPlayer stop]; [playListController updateView]; } /************************************************************************************/ - (IBAction)switchFullscreen:(id)sender { if ([myPlayer status] > 0) { // if mplayer is playing if ([myPlayer fullscreen]) [myPlayer setFullscreen:NO]; else [myPlayer setFullscreen:YES]; [myPlayer applySettingsWithRestart:NO]; } else { // if it is not playing // set the item to play if ([playListController indexOfSelectedItem] < 0) [playListController selectItemAtIndex:0]; // set it to play in fullecreen [myPlayer setFullscreen:YES]; // play the item [self playItem:[playListController selectedItem]]; } } /************************************************************************************/ - (IBAction)displayStats:(id)sender { [myPlayer setUpdateStatistics:YES]; [statsPanel makeKeyAndOrderFront:self]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(statsClosed) name: NSWindowWillCloseNotification object:statsPanel]; } /************************************************************************************ NOTIFICATION OBSERVERS ************************************************************************************/ - (void) appFinishedLaunching { NSUserDefaults *prefs = [appController preferences]; // play the last played movie if it is set to do so if ([prefs objectForKey:@"RememberPosition"] && [prefs objectForKey:@"LastTrack"] && ![myPlayer isRunning]) { if ([[prefs objectForKey:@"RememberPosition"] isEqualToString:@"YES"] && [prefs objectForKey:@"LastTrack"]) { [self playItem:[playListController itemAtIndex:[[prefs objectForKey:@"LastTrack"] intValue]]]; [playListController selectItemAtIndex:[[prefs objectForKey:@"LastTrack"] intValue]]; } } [prefs removeObjectForKey:@"LastTrack"]; } /************************************************************************************/ - (void) appShouldTerminate { // save values before all is saved to disk and released if ([myPlayer status] > 0 && [[appController preferences] objectForKey:@"RememberPosition"]) { if ([[[appController preferences] objectForKey:@"RememberPosition"] isEqualToString:@"YES"]) { [[appController preferences] setObject:[NSNumber numberWithInt:[playListController indexOfItem:myPlayingItem]] forKey:@"LastTrack"]; if (myPlayingItem) [myPlayingItem setObject:[NSNumber numberWithFloat:[myPlayer seconds]] forKey:@"LastSeconds"]; } } // stop mplayer [myPlayer stop]; } /************************************************************************************/ // when application is terminating - (void)appTerminating { // remove observers [[NSNotificationCenter defaultCenter] removeObserver:self name: @"PlaybackStartNotification" object:myPlayer]; [[NSNotificationCenter defaultCenter] removeObserver:self name: @"MIStateUpdatedNotification" object:myPlayer]; [playImage release]; [pauseImage release]; [playImageMini release]; [pauseImageMini release]; [myPlayer release]; } /************************************************************************************/ - (void) playbackStarted { // the info dictionary should now be ready to be imported if ([myPlayer info] && myPlayingItem) { [myPlayingItem addEntriesFromDictionary:[myPlayer info]]; } [playListController updateView]; } /************************************************************************************/ - (void) statsClosed { [myPlayer setUpdateStatistics:NO]; [[NSNotificationCenter defaultCenter] removeObserver:self name: @"NSWindowWillCloseNotification" object:statsPanel]; } /************************************************************************************/ - (void) statusUpdate:(NSNotification *)notification; { int seconds; NSMutableDictionary *playingItem = myPlayingItem; // reset Idle time - Carbon PowerManager calls if ([playingItem objectForKey:@"ID_VIDEO_FORMAT"]) // if there is a video #ifdef __COCOA__ UpdateSystemActivity (UsrActivity); // do not dim the display #endif /* else // if there's only audio UpdateSystemActivity (OverallAct); // avoid sleeping only */ // status did change if ([notification userInfo] && [[notification userInfo] objectForKey:@"PlayerStatus"]) { NSString *status; // status is changing // switch Play menu item title and playbutton image switch ([[[notification userInfo] objectForKey:@"PlayerStatus"] unsignedIntValue]) { case kOpening : case kBuffering : case kIndexing : case kPlaying : [playButton setImage:pauseImage]; [playButtonMini setImage:pauseImageMini]; [playMenuItem setTitle:NSLocalizedString(@"Pause",nil)]; [playDockMenuItem setTitle:NSLocalizedString(@"Pause",nil)]; break; case kPaused : case kStopped : case kFinished : [playButton setImage:playImage]; [playButtonMini setImage:playImageMini]; [playMenuItem setTitle:NSLocalizedString(@"Play",nil)]; [playDockMenuItem setTitle:NSLocalizedString(@"Play",nil)]; break; } switch ([[[notification userInfo] objectForKey:@"PlayerStatus"] unsignedIntValue]) { case kOpening : status = NSLocalizedString(@"Opening",nil); if ([playingItem objectForKey:@"ItemTitle"]) { [titleBox setStringValue:[playingItem objectForKey:@"ItemTitle"]]; [titleBoxMini setStringValue:[playingItem objectForKey:@"ItemTitle"]]; } else { [titleBox setStringValue:[[playingItem objectForKey:@"MovieFile"] lastPathComponent]]; [titleBoxMini setStringValue:[[playingItem objectForKey:@"MovieFile"] lastPathComponent]]; } // progress bars #ifdef __COCOA__ [progressBar setStyle:NSScrubbingBarProgressStyle]; #endif [progressBar setIndeterminate:YES]; break; case kBuffering : status = NSLocalizedString(@"Buffering",nil); // progress bars #ifdef __COCOA__ [progressBar setStyle:NSScrubbingBarProgressStyle]; #endif [progressBar setIndeterminate:YES]; break; case kIndexing : status = NSLocalizedString(@"Indexing",nil); // progress bars #ifdef __COCOA__ [progressBar setStyle:NSScrubbingBarProgressStyle]; #endif [progressBar setMaxValue:100]; [progressBar setIndeterminate:NO]; break; case kPlaying : status = NSLocalizedString(@"Playing",nil); // set default state of scrubbing bar #ifdef __COCOA__ [progressBar setStyle:NSScrubbingBarEmptyStyle]; #endif [progressBar setIndeterminate:NO]; [progressBar setMaxValue:100]; if ([playingItem objectForKey:@"ID_LENGTH"]) { if ([[playingItem objectForKey:@"ID_LENGTH"] intValue] > 0) { [progressBar setMaxValue: [[playingItem objectForKey:@"ID_LENGTH"] intValue]]; #ifdef __COCOA__ [progressBar setStyle:NSScrubbingBarPositionStyle]; #endif } } break; case kPaused : status = NSLocalizedString(@"Paused",nil); // stop progress bars break; case kStopped : case kFinished : // reset status panel status = NSLocalizedString(@"N/A",nil); [statsCPUUsageBox setStringValue:status]; [statsCacheUsageBox setStringValue:status]; [statsAVsyncBox setStringValue:status]; [statsDroppedBox setStringValue:status]; [statsPostProcBox setStringValue:status]; // reset status box status = @""; [titleBox setStringValue:@""]; [titleBoxMini setStringValue:@""]; [timeBox setStringValue:@"0:00:00"]; [timeBoxMini setStringValue:@"0:00:00"]; // hide progress bars #ifdef __COCOA__ [progressBar setStyle:NSScrubbingBarEmptyStyle]; #endif [progressBar setDoubleValue:0]; [progressBar setIndeterminate:NO]; // release the retained playing item [playingItem autorelease]; myPlayingItem = nil; // update state of playlist [playListController updateView]; // if playback finished itself (not by user) let playListController know if ([[[notification userInfo] objectForKey:@"PlayerStatus"] unsignedIntValue] == kFinished) [playListController finishedPlayingItem:playingItem]; break; } [statsStatusBox setStringValue:status]; [statusBox setStringValue:status]; [statusBoxMini setStringValue:status]; } seconds = (int)[myPlayer seconds]; // update values switch ([myPlayer status]) { case kOpening : break; case kBuffering : if ([statsPanel isVisible]) [statsCacheUsageBox setStringValue:[NSString localizedStringWithFormat:@"%3.1f %%", [myPlayer cacheUsage]]]; break; case kIndexing : [progressBar setDoubleValue:[myPlayer cacheUsage]]; break; case kPlaying : if ([[progressBar window] isVisible]) { if ([playingItem objectForKey:@"ID_LENGTH"]) if ([[playingItem objectForKey:@"ID_LENGTH"] intValue] > 0) [progressBar setDoubleValue:[myPlayer seconds]]; else [progressBar setDoubleValue:0]; else [progressBar setDoubleValue:0]; } if ([[timeBox window] isVisible]) [timeBox setStringValue:[NSString stringWithFormat:@"%01d:%02d:%02d", seconds/3600,(seconds%3600)/60,seconds%60]]; if ([[timeBoxMini window] isVisible]) [timeBoxMini setStringValue:[NSString stringWithFormat:@"%01d:%02d:%02d", seconds/3600,(seconds%3600)/60,seconds%60]]; // stats window if ([statsPanel isVisible]) { [statsCPUUsageBox setStringValue:[NSString localizedStringWithFormat:@"%d %%", [myPlayer cpuUsage]]]; [statsCacheUsageBox setStringValue:[NSString localizedStringWithFormat:@"%d %%", [myPlayer cacheUsage]]]; [statsAVsyncBox setStringValue:[NSString localizedStringWithFormat:@"%3.1f", [myPlayer syncDifference]]]; [statsDroppedBox setStringValue:[NSString localizedStringWithFormat:@"%d", [myPlayer droppedFrames]]]; [statsPostProcBox setStringValue:[NSString localizedStringWithFormat:@"%d", [myPlayer postProcLevel]]]; } break; case kPaused : break; } } /************************************************************************************/ - (BOOL) validateMenuItem:(NSMenuItem *)aMenuItem { if ((aMenuItem == stopMenuItem || aMenuItem == stopDockMenuItem) && ([myPlayer status] == kStopped || [myPlayer status] == kFinished)) { return NO; } return YES; } /************************************************************************************/ - (void) progresBarClicked:(NSNotification *)notification { if ([myPlayer status] == kPlaying || [myPlayer status] == kPaused) { int theMode = MIPercentSeekingMode; if ([myPlayingItem objectForKey:@"ID_LENGTH"]) if ([[myPlayingItem objectForKey:@"ID_LENGTH"] floatValue] != 0) theMode = MIAbsoluteSeekingMode; [myPlayer seek:[[[notification userInfo] objectForKey:@"SBClickedValue"] floatValue] mode:theMode]; } } /************************************************************************************ DELEGATE METHODS ************************************************************************************/ // main window delegates // exekutes when window zoom box is clicked - (BOOL)windowShouldZoom:(NSWindow *)sender toFrame:(NSRect)newFrame { if (sender == mainWindow) { [mainWindow orderOut:nil]; [miniWindow makeKeyAndOrderFront:nil]; [[appController preferences] setObject:@"YES" forKey:@"MinimizedWindow"]; return NO; } if (sender == miniWindow) { [miniWindow orderOut:nil]; [mainWindow makeKeyAndOrderFront:nil]; [[appController preferences] setObject:@"NO" forKey:@"MinimizedWindow"]; return NO; } return YES; } /************************************************************************************/ // executes when window is closed - (void)windowWillClose:(NSNotification *)aNotification { [appController quitApp]; } @end