Commit b030f616 authored by Pierre d'Herbemont's avatar Pierre d'Herbemont

Remove vlc_app. Unfinished, and doesn't belong here.

parent 32ef2433
Binary files a/projects/macosx/vlc_app/English.lproj/InfoPlist.strings and /dev/null differ
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBClasses</key>
<array>
<dict>
<key>CLASS</key>
<string>NSView</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>SUPERCLASS</key>
<string>NSResponder</string>
</dict>
<dict>
<key>ACTIONS</key>
<dict>
<key>addPlaylist</key>
<string>id</string>
<key>mediaListViewItemDoubleClicked</key>
<string>id</string>
<key>newMainWindow</key>
<string>id</string>
</dict>
<key>CLASS</key>
<string>VLCController</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>OUTLETS</key>
<dict>
<key>categoriesListView</key>
<string>id</string>
<key>fillScreenButton</key>
<string>id</string>
<key>mediaListItemFetchedStatus</key>
<string>id</string>
<key>mediaListItemsCount</key>
<string>id</string>
<key>mediaListSearchField</key>
<string>id</string>
<key>mediaListView</key>
<string>id</string>
<key>videoView</key>
<string>VLCBrowsableVideoView</string>
</dict>
<key>SUPERCLASS</key>
<string>NSObject</string>
</dict>
<dict>
<key>ACTIONS</key>
<dict>
<key>mediaListViewItemDoubleClicked</key>
<string>id</string>
<key>videoViewItemClicked</key>
<string>id</string>
</dict>
<key>CLASS</key>
<string>VLCMainWindowController</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>OUTLETS</key>
<dict>
<key>addPlaylistButton</key>
<string>NSButton</string>
<key>categoriesListView</key>
<string>NSOutlineView</string>
<key>categoriesTreeController</key>
<string>NSTreeController</string>
<key>controller</key>
<string>VLCController</string>
<key>mainSplitView</key>
<string>VLCOneSplitView</string>
<key>mediaArrayController</key>
<string>VLCMediaArrayController</string>
<key>mediaListView</key>
<string>NSTableView</string>
<key>mediaPlayer</key>
<string>VLCMediaPlayer</string>
<key>mediaPlayerBackwardPrevButton</key>
<string>NSButton</string>
<key>mediaPlayerForwardNextButton</key>
<string>NSButton</string>
<key>mediaPlayerPlayPauseStopButton</key>
<string>NSButton</string>
<key>removePlaylistButton</key>
<string>NSButton</string>
<key>toolbarMediaAudioVolume</key>
<string>NSView</string>
<key>toolbarMediaControl</key>
<string>NSView</string>
<key>toolbarMediaDescription</key>
<string>NSView</string>
<key>videoView</key>
<string>VLCBrowsableVideoView</string>
</dict>
<key>SUPERCLASS</key>
<string>NSWindowController</string>
</dict>
<dict>
<key>CLASS</key>
<string>FirstResponder</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>SUPERCLASS</key>
<string>NSObject</string>
</dict>
<dict>
<key>CLASS</key>
<string>VLCOneSplitView</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>SUPERCLASS</key>
<string>NSSplitView</string>
</dict>
<dict>
<key>CLASS</key>
<string>VLCMediaArrayController</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>SUPERCLASS</key>
<string>NSArrayController</string>
</dict>
<dict>
<key>ACTIONS</key>
<dict>
<key>moveDown</key>
<string>id</string>
<key>moveUp</key>
<string>id</string>
</dict>
<key>CLASS</key>
<string>VLCBrowsableVideoView</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>OUTLETS</key>
<dict>
<key>mainWindowController</key>
<string>VLCMainWindowController</string>
<key>selectedObject</key>
<string>id</string>
<key>target</key>
<string>id</string>
</dict>
<key>SUPERCLASS</key>
<string>VLCVideoView</string>
</dict>
<dict>
<key>CLASS</key>
<string>VLCVideoView</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>SUPERCLASS</key>
<string>NSView</string>
</dict>
<dict>
<key>CLASS</key>
<string>VLCMediaPlayer</string>
<key>LANGUAGE</key>
<string>ObjC</string>
</dict>
</array>
<key>IBVersion</key>
<string>1</string>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IBFramework Version</key>
<string>629</string>
<key>IBOldestOS</key>
<integer>5</integer>
<key>IBOpenObjects</key>
<array/>
<key>IBSystem Version</key>
<string>9B18</string>
<key>targetFramework</key>
<string>IBCocoaFramework</string>
</dict>
</plist>
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>org.videolan.vlc</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
</dict>
</plist>
/*****************************************************************************
* AppleRemote.h
* AppleRemote
* $Id$
*
* Created by Martin Kahr on 11.03.06 under a MIT-style license.
* Copyright (c) 2006 martinkahr.com. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*****************************************************************************
*
* Note that changes made by any members or contributors of the VideoLAN team
* (i.e. changes that were checked in exclusively into one of VideoLAN's source code
* repositories) are licensed under the GNU General Public License version 2,
* or (at your option) any later version.
* Thus, the following statements apply to our changes:
*
* Copyright (C) 2006-2007 the VideoLAN team
* Authors: Eric Petit <titer@m0k.org>
* Felix Kühne <fkuehne at videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <mach/mach.h>
#import <mach/mach_error.h>
#import <IOKit/IOKitLib.h>
#import <IOKit/IOCFPlugIn.h>
#import <IOKit/hid/IOHIDLib.h>
#import <IOKit/hid/IOHIDKeys.h>
enum AppleRemoteEventIdentifier
{
kRemoteButtonVolume_Plus =1<<1,
kRemoteButtonVolume_Minus =1<<2,
kRemoteButtonMenu =1<<3,
kRemoteButtonPlay =1<<4,
kRemoteButtonRight =1<<5,
kRemoteButtonLeft =1<<6,
kRemoteButtonRight_Hold =1<<7,
kRemoteButtonLeft_Hold =1<<8,
kRemoteButtonMenu_Hold =1<<9,
kRemoteButtonPlay_Sleep =1<<10,
kRemoteControl_Switched =1<<11,
kRemoteButtonVolume_Plus_Hold =1<<12,
kRemoteButtonVolume_Minus_Hold =1<<13
};
typedef enum AppleRemoteEventIdentifier AppleRemoteEventIdentifier;
/* Encapsulates usage of the apple remote control
This class is implemented as a singleton as there is exactly one remote per machine (until now)
The class is not thread safe
*/
@interface AppleRemote : NSObject {
IOHIDDeviceInterface** hidDeviceInterface;
IOHIDQueueInterface** queue;
NSMutableArray* allCookies;
NSMutableDictionary* cookieToButtonMapping;
BOOL openInExclusiveMode;
BOOL simulatePlusMinusHold;
BOOL processesBacklog;
/* state for simulating plus/minus hold */
BOOL lastEventSimulatedHold;
AppleRemoteEventIdentifier lastPlusMinusEvent;
NSTimeInterval lastPlusMinusEventTime;
int remoteId;
unsigned int clickCountEnabledButtons;
NSTimeInterval maxClickTimeDifference;
NSTimeInterval lastClickCountEventTime;
AppleRemoteEventIdentifier lastClickCountEvent;
unsigned int eventClickCount;
IBOutlet id delegate;
}
- (int) remoteId;
- (BOOL) isRemoteAvailable;
- (BOOL) isListeningToRemote;
- (void) setListeningToRemote: (BOOL) value;
- (BOOL) isOpenInExclusiveMode;
- (void) setOpenInExclusiveMode: (BOOL) value;
/* click counting makes it possible to recognize if the user has pressed a button repeatedly
* click counting does delay each event as it has to wait if there is another event (second click)
* therefore there is a slight time difference (maximumClickCountTimeDifference) between a single click
* of the user and the call of your delegate method
* click counting can be enabled individually for specific buttons. Use the property clickCountEnableButtons
* to set the buttons for which click counting shall be enabled */
- (BOOL) clickCountingEnabled;
- (void) setClickCountingEnabled: (BOOL) value;
- (unsigned int) clickCountEnabledButtons;
- (void) setClickCountEnabledButtons: (unsigned int)value;
/* the maximum time difference till which clicks are recognized as multi clicks */
- (NSTimeInterval) maximumClickCountTimeDifference;
- (void) setMaximumClickCountTimeDifference: (NSTimeInterval) timeDiff;
/* When your application needs to much time on the main thread when processing an event other events
* may already be received which are put on a backlog. As soon as your main thread
* has some spare time this backlog is processed and may flood your delegate with calls.
* Backlog processing is turned off by default. */
- (BOOL) processesBacklog;
- (void) setProcessesBacklog: (BOOL) value;
/* Sets an NSApplication delegate which starts listening when application is becoming active
* and stops listening when application resigns being active.
* If an NSApplication delegate has been already set all method calls will be forwarded to this delegate, too. */
- (BOOL) listeningOnAppActivate;
- (void) setListeningOnAppActivate: (BOOL) value;
/* Simulating plus/minus hold does deactivate sending of individual requests for plus/minus pressed down/released.
* Instead special hold events are being triggered when the user is pressing and holding plus/minus for a small period.
* With simulating enabled the plus/minus buttons do behave as the left/right buttons */
- (BOOL) simulatesPlusMinusHold;
- (void) setSimulatesPlusMinusHold: (BOOL) value;
/* Delegates are not retained */
- (void) setDelegate: (id) delegate;
- (id) delegate;
- (IBAction) startListening: (id) sender;
- (IBAction) stopListening: (id) sender;
@end
@interface AppleRemote (Singleton)
+ (AppleRemote*) sharedRemote;
@end
/* Method definitions for the delegate of the AppleRemote class */
@interface NSObject(NSAppleRemoteDelegate)
- (void) appleRemoteButton: (AppleRemoteEventIdentifier)buttonIdentifier pressedDown: (BOOL) pressedDown clickCount: (unsigned int) count;
@end
@interface AppleRemote (PrivateMethods)
- (void) setRemoteId: (int) aValue;
- (NSDictionary*) cookieToButtonMapping;
- (IOHIDQueueInterface**) queue;
- (IOHIDDeviceInterface**) hidDeviceInterface;
- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues;
@end
@interface AppleRemote (IOKitMethods)
- (io_object_t) findAppleRemoteDevice;
- (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice;
- (BOOL) initializeCookies;
- (BOOL) openDevice;
@end
/* A NSApplication delegate which is used to activate and deactivate listening to the remote control
* dependent on the activation state of your application.
* All events are delegated to the original NSApplication delegate if necessary */
@interface AppleRemoteApplicationDelegate : NSObject {
id applicationDelegate;
}
- (id) initWithApplicationDelegate: (id) delegate;
- (id) applicationDelegate;
@end
/*****************************************************************************
* AppleRemote.m
* AppleRemote
* $Id$
*
* Created by Martin Kahr on 11.03.06 under a MIT-style license.
* Copyright (c) 2006 martinkahr.com. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*****************************************************************************
*
* Note that changes made by any members or contributors of the VideoLAN team
* (i.e. changes that were exclusively checked in to one of VideoLAN's source code
* repositories) are licensed under the GNU General Public License version 2,
* or (at your option) any later version.
* Thus, the following statements apply to our changes:
*
* Copyright (C) 2006-2007 the VideoLAN team
* Authors: Eric Petit <titer@m0k.org>
* Felix Kühne <fkuehne at videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "AppleRemote.h"
#define MACOS_VERSION [[[NSDictionary dictionaryWithContentsOfFile: \
@"/System/Library/CoreServices/SystemVersion.plist"] \
objectForKey: @"ProductVersion"] floatValue]
const char* AppleRemoteDeviceName = "AppleIRController";
const int REMOTE_SWITCH_COOKIE=19;
const NSTimeInterval DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE=0.35;
const NSTimeInterval HOLD_RECOGNITION_TIME_INTERVAL=0.4;
@implementation AppleRemote
#pragma public interface
- (id) init {
if ( self = [super init] ) {
openInExclusiveMode = YES;
queue = NULL;
hidDeviceInterface = NULL;
cookieToButtonMapping = [[NSMutableDictionary alloc] init];
if( MACOS_VERSION < 10.5f )
{
/* use the traditional cookies for Tiger (and Panther, if it is supported by the frame app) */
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Plus] forKey:@"14_12_11_6_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Minus] forKey:@"14_13_11_6_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"14_7_6_14_7_6_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"14_8_6_14_8_6_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"14_9_6_14_9_6_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"14_10_6_14_10_6_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"14_6_4_2_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"14_6_3_2_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"14_6_14_6_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"18_14_6_18_14_6_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"];
}
else
{
/* we're on Leopard and need to use a new set of cookies */
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Plus] forKey:@"31_29_28_18_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonVolume_Minus] forKey:@"31_30_28_18_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu] forKey:@"31_20_18_31_20_18_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay] forKey:@"31_21_18_31_21_18_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight] forKey:@"31_22_18_31_22_18_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft] forKey:@"31_23_18_31_23_18_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonRight_Hold] forKey:@"31_18_4_2_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonLeft_Hold] forKey:@"31_18_3_2_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonMenu_Hold] forKey:@"31_18_31_18_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteButtonPlay_Sleep] forKey:@"35_31_18_35_31_18_"];
[cookieToButtonMapping setObject:[NSNumber numberWithInt:kRemoteControl_Switched] forKey:@"19_"];
}
/* defaults */
[self setSimulatesPlusMinusHold: YES];
maxClickTimeDifference = DEFAULT_MAXIMUM_CLICK_TIME_DIFFERENCE;
}
return self;
}
- (void) dealloc {
[self stopListening:self];
[cookieToButtonMapping release];
[super dealloc];
}
- (int) remoteId {
return remoteId;
}
- (BOOL) isRemoteAvailable {
io_object_t hidDevice = [self findAppleRemoteDevice];
if (hidDevice != 0) {
IOObjectRelease(hidDevice);
return YES;
} else {
return NO;
}
}
- (BOOL) isListeningToRemote {
return (hidDeviceInterface != NULL && allCookies != NULL && queue != NULL);
}
- (void) setListeningToRemote: (BOOL) value {
if (value == NO) {
[self stopListening:self];
} else {
[self startListening:self];
}
}
/* Delegates are not retained!
* http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CommunicatingWithObjects/chapter_6_section_4.html
* Delegating objects do not (and should not) retain their delegates.
* However, clients of delegating objects (applications, usually) are responsible for ensuring that their delegates are around
* to receive delegation messages. To do this, they may have to retain the delegate. */
- (void) setDelegate: (id) _delegate {
if (_delegate && [_delegate respondsToSelector:@selector(appleRemoteButton:pressedDown:clickCount:)]==NO) return;
delegate = _delegate;
}
- (id) delegate {
return delegate;
}
- (BOOL) isOpenInExclusiveMode {
return openInExclusiveMode;
}
- (void) setOpenInExclusiveMode: (BOOL) value {
openInExclusiveMode = value;
}
- (BOOL) clickCountingEnabled {
return clickCountEnabledButtons != 0;
}
- (void) setClickCountingEnabled: (BOOL) value {
if (value) {
[self setClickCountEnabledButtons: kRemoteButtonVolume_Plus | kRemoteButtonVolume_Minus | kRemoteButtonPlay | kRemoteButtonLeft | kRemoteButtonRight | kRemoteButtonMenu];
} else {
[self setClickCountEnabledButtons: 0];
}
}
- (unsigned int) clickCountEnabledButtons {
return clickCountEnabledButtons;
}
- (void) setClickCountEnabledButtons: (unsigned int)value {
clickCountEnabledButtons = value;
}
- (NSTimeInterval) maximumClickCountTimeDifference {
return maxClickTimeDifference;
}
- (void) setMaximumClickCountTimeDifference: (NSTimeInterval) timeDiff {
maxClickTimeDifference = timeDiff;
}
- (BOOL) processesBacklog {
return processesBacklog;
}
- (void) setProcessesBacklog: (BOOL) value {
processesBacklog = value;
}
- (BOOL) listeningOnAppActivate {
id appDelegate = [NSApp delegate];
return (appDelegate!=nil && [appDelegate isKindOfClass: [AppleRemoteApplicationDelegate class]]);
}
- (void) setListeningOnAppActivate: (BOOL) value {
if (value) {
if ([self listeningOnAppActivate]) return;
AppleRemoteApplicationDelegate* appDelegate = [[AppleRemoteApplicationDelegate alloc] initWithApplicationDelegate: [NSApp delegate]];
/* NSApp does not retain its delegate therefore we keep retain count on 1 */
[NSApp setDelegate: appDelegate];
} else {
if ([self listeningOnAppActivate]==NO) return;
AppleRemoteApplicationDelegate* appDelegate = (AppleRemoteApplicationDelegate*)[NSApp delegate];
id previousAppDelegate = [appDelegate applicationDelegate];
[NSApp setDelegate: previousAppDelegate];
[appDelegate release];
}
}
- (BOOL) simulatesPlusMinusHold {
return simulatePlusMinusHold;
}
- (void) setSimulatesPlusMinusHold: (BOOL) value {
simulatePlusMinusHold = value;
}
- (IBAction) startListening: (id) sender {
if ([self isListeningToRemote]) return;
io_object_t hidDevice = [self findAppleRemoteDevice];
if (hidDevice == 0) return;
if ([self createInterfaceForDevice:hidDevice] == NULL) {
goto error;
}
if ([self initializeCookies]==NO) {
goto error;
}
if ([self openDevice]==NO) {
goto error;
}
goto cleanup;
error:
[self stopListening:self];
cleanup:
IOObjectRelease(hidDevice);
}
- (IBAction) stopListening: (id) sender {
if (queue != NULL) {
(*queue)->stop(queue);
//dispose of queue
(*queue)->dispose(queue);
//release the queue we allocated
(*queue)->Release(queue);
queue = NULL;
}
if (allCookies != nil) {
[allCookies autorelease];
allCookies = nil;
}
if (hidDeviceInterface != NULL) {
//close the device
(*hidDeviceInterface)->close(hidDeviceInterface);
//release the interface
(*hidDeviceInterface)->Release(hidDeviceInterface);
hidDeviceInterface = NULL;
}
}
@end
@implementation AppleRemote (Singleton)
static AppleRemote* sharedInstance=nil;
+ (AppleRemote*) sharedRemote {
@synchronized(self) {
if (sharedInstance == nil) {
sharedInstance = [[self alloc] init];
}
}
return sharedInstance;
}
+ (id)allocWithZone:(NSZone *)zone {
@synchronized(self) {
if (sharedInstance == nil) {
return [super allocWithZone:zone];
}
}
return sharedInstance;
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return UINT_MAX; //denotes an object that cannot be released
}
- (void)release {
//do nothing
}
- (id)autorelease {
return self;
}
@end
@implementation AppleRemote (PrivateMethods)
- (void) setRemoteId: (int) value {
remoteId = value;
}
- (IOHIDQueueInterface**) queue {
return queue;
}
- (IOHIDDeviceInterface**) hidDeviceInterface {
return hidDeviceInterface;
}
- (NSDictionary*) cookieToButtonMapping {
return cookieToButtonMapping;
}
- (NSString*) validCookieSubstring: (NSString*) cookieString {
if (cookieString == nil || [cookieString length] == 0) return nil;
NSEnumerator* keyEnum = [[self cookieToButtonMapping] keyEnumerator];
NSString* key;
while(key = [keyEnum nextObject]) {
NSRange range = [cookieString rangeOfString:key];
if (range.location == 0) return key;
}
return nil;
}
- (void) sendSimulatedPlusMinusEvent: (id) time {
BOOL startSimulateHold = NO;
AppleRemoteEventIdentifier event = lastPlusMinusEvent;
@synchronized(self) {
startSimulateHold = (lastPlusMinusEvent>0 && lastPlusMinusEventTime == [time doubleValue]);
}
if (startSimulateHold) {
lastEventSimulatedHold = YES;
event = (event==kRemoteButtonVolume_Plus) ? kRemoteButtonVolume_Plus_Hold : kRemoteButtonVolume_Minus_Hold;
[delegate appleRemoteButton:event pressedDown: YES clickCount: 1];
}
}
- (void) sendRemoteButtonEvent: (AppleRemoteEventIdentifier) event pressedDown: (BOOL) pressedDown {
if (delegate) {
if (simulatePlusMinusHold) {
if (event == kRemoteButtonVolume_Plus || event == kRemoteButtonVolume_Minus) {
if (pressedDown) {
lastPlusMinusEvent = event;
lastPlusMinusEventTime = [NSDate timeIntervalSinceReferenceDate];
[self performSelector:@selector(sendSimulatedPlusMinusEvent:)
withObject:[NSNumber numberWithDouble:lastPlusMinusEventTime]
afterDelay:HOLD_RECOGNITION_TIME_INTERVAL];
return;
} else {
if (lastEventSimulatedHold) {
event = (event==kRemoteButtonVolume_Plus) ? kRemoteButtonVolume_Plus_Hold : kRemoteButtonVolume_Minus_Hold;
lastPlusMinusEvent = 0;
lastEventSimulatedHold = NO;
} else {
@synchronized(self) {
lastPlusMinusEvent = 0;
}
pressedDown = YES;
}
}
}
}
if (([self clickCountEnabledButtons] & event) == event) {
if (pressedDown==NO && (event == kRemoteButtonVolume_Minus || event == kRemoteButtonVolume_Plus)) {
return; // this one is triggered automatically by the handler
}
NSNumber* eventNumber;
NSNumber* timeNumber;
@synchronized(self) {
lastClickCountEventTime = [NSDate timeIntervalSinceReferenceDate];
if (lastClickCountEvent == event) {
eventClickCount = eventClickCount + 1;
} else {
eventClickCount = 1;
}
lastClickCountEvent = event;
timeNumber = [NSNumber numberWithDouble:lastClickCountEventTime];
eventNumber= [NSNumber numberWithUnsignedInt:event];
}
[self performSelector: @selector(executeClickCountEvent:)
withObject: [NSArray arrayWithObjects:eventNumber, timeNumber, nil]
afterDelay: maxClickTimeDifference];
} else {
[delegate appleRemoteButton:event pressedDown: pressedDown clickCount:1];
}
}
}
- (void) executeClickCountEvent: (NSArray*) values {
AppleRemoteEventIdentifier event = [[values objectAtIndex: 0] unsignedIntValue];
NSTimeInterval eventTimePoint = [[values objectAtIndex: 1] doubleValue];
BOOL finishedClicking = NO;
int finalClickCount = eventClickCount;
@synchronized(self) {
finishedClicking = (event != lastClickCountEvent || eventTimePoint == lastClickCountEventTime);
if (finishedClicking) eventClickCount = 0;
}
if (finishedClicking) {
[delegate appleRemoteButton:event pressedDown: YES clickCount:finalClickCount];
if ([self simulatesPlusMinusHold]==NO && (event == kRemoteButtonVolume_Minus || event == kRemoteButtonVolume_Plus)) {
// trigger a button release event, too
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow:0.1]];
[delegate appleRemoteButton:event pressedDown: NO clickCount:finalClickCount];
}
}
}
- (void) handleEventWithCookieString: (NSString*) cookieString sumOfValues: (SInt32) sumOfValues {
/*
if (previousRemainingCookieString) {
cookieString = [previousRemainingCookieString stringByAppendingString: cookieString];
NSLog(@"New cookie string is %@", cookieString);
[previousRemainingCookieString release], previousRemainingCookieString=nil;
}*/
if (cookieString == nil || [cookieString length] == 0) return;
NSNumber* buttonId = [[self cookieToButtonMapping] objectForKey: cookieString];
if (buttonId != nil) {
[self sendRemoteButtonEvent: [buttonId intValue] pressedDown: (sumOfValues>0)];
} else {
// let's see if a number of events are stored in the cookie string. this does
// happen when the main thread is too busy to handle all incoming events in time.
NSString* subCookieString;
NSString* lastSubCookieString=nil;
while(subCookieString = [self validCookieSubstring: cookieString]) {
cookieString = [cookieString substringFromIndex: [subCookieString length]];
lastSubCookieString = subCookieString;
if (processesBacklog) [self handleEventWithCookieString: subCookieString sumOfValues:sumOfValues];
}
if (processesBacklog == NO && lastSubCookieString != nil) {
// process the last event of the backlog and assume that the button is not pressed down any longer.
// The events in the backlog do not seem to be in order and therefore (in rare cases) the last event might be
// a button pressed down event while in reality the user has released it.
// NSLog(@"processing last event of backlog");
[self handleEventWithCookieString: lastSubCookieString sumOfValues:0];
}
if ([cookieString length] > 0) {
NSLog(@"Unknown button for cookiestring %@", cookieString);
}
}
}
@end
/* Callback method for the device queue
Will be called for any event of any type (cookie) to which we subscribe
*/
static void QueueCallbackFunction(void* target, IOReturn result, void* refcon, void* sender) {
AppleRemote* remote = (AppleRemote*)target;
IOHIDEventStruct event;
AbsoluteTime zeroTime = {0,0};
NSMutableString* cookieString = [NSMutableString string];
SInt32 sumOfValues = 0;
while (result == kIOReturnSuccess)
{
result = (*[remote queue])->getNextEvent([remote queue], &event, zeroTime, 0);
if ( result != kIOReturnSuccess )
continue;
//printf("%d %d %d\n", event.elementCookie, event.value, event.longValue);
if (REMOTE_SWITCH_COOKIE == (int)event.elementCookie) {
[remote setRemoteId: event.value];
[remote handleEventWithCookieString: @"19_" sumOfValues: 0];
} else {
if (((int)event.elementCookie)!=5) {
sumOfValues+=event.value;
[cookieString appendString:[NSString stringWithFormat:@"%d_", event.elementCookie]];
}
}
}
[remote handleEventWithCookieString: cookieString sumOfValues: sumOfValues];
}
@implementation AppleRemote (IOKitMethods)
- (IOHIDDeviceInterface**) createInterfaceForDevice: (io_object_t) hidDevice {
io_name_t className;
IOCFPlugInInterface** plugInInterface = NULL;
HRESULT plugInResult = S_OK;
SInt32 score = 0;
IOReturn ioReturnValue = kIOReturnSuccess;
hidDeviceInterface = NULL;
ioReturnValue = IOObjectGetClass(hidDevice, className);
if (ioReturnValue != kIOReturnSuccess) {
NSLog(@"Error: Failed to get class name.");
return NULL;
}
ioReturnValue = IOCreatePlugInInterfaceForService(hidDevice,
kIOHIDDeviceUserClientTypeID,
kIOCFPlugInInterfaceID,
&plugInInterface,
&score);
if (ioReturnValue == kIOReturnSuccess)
{
//Call a method of the intermediate plug-in to create the device interface
plugInResult = (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), (LPVOID) &hidDeviceInterface);
if (plugInResult != S_OK) {
NSLog(@"Error: Couldn't create HID class device interface");
}
// Release
if (plugInInterface) (*plugInInterface)->Release(plugInInterface);
}
return hidDeviceInterface;
}
- (io_object_t) findAppleRemoteDevice {
CFMutableDictionaryRef hidMatchDictionary = NULL;
IOReturn ioReturnValue = kIOReturnSuccess;
io_iterator_t hidObjectIterator = 0;
io_object_t hidDevice = 0;
// Set up a matching dictionary to search the I/O Registry by class
// name for all HID class devices
hidMatchDictionary = IOServiceMatching(AppleRemoteDeviceName);
// Now search I/O Registry for matching devices.
ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, hidMatchDictionary, &hidObjectIterator);
if ((ioReturnValue == kIOReturnSuccess) && (hidObjectIterator != 0)) {
hidDevice = IOIteratorNext(hidObjectIterator);
}
// release the iterator
IOObjectRelease(hidObjectIterator);
return hidDevice;
}
- (BOOL) initializeCookies {
IOHIDDeviceInterface122** handle = (IOHIDDeviceInterface122**)hidDeviceInterface;
IOHIDElementCookie cookie;
long usage;
long usagePage;
id object;
NSArray* elements = nil;
NSDictionary* element;
IOReturn success;
if (!handle || !(*handle)) return NO;
/* Copy all elements, since we're grabbing most of the elements
* for this device anyway, and thus, it's faster to iterate them
* ourselves. When grabbing only one or two elements, a matching
* dictionary should be passed in here instead of NULL. */
success = (*handle)->copyMatchingElements(handle, NULL, (CFArrayRef*)&elements);
if (success == kIOReturnSuccess) {
[elements autorelease];
/*
cookies = calloc(NUMBER_OF_APPLE_REMOTE_ACTIONS, sizeof(IOHIDElementCookie));
memset(cookies, 0, sizeof(IOHIDElementCookie) * NUMBER_OF_APPLE_REMOTE_ACTIONS);
*/
allCookies = [[NSMutableArray alloc] init];
int i;
for (i=0; i< [elements count]; i++) {
element = [elements objectAtIndex:i];
//Get cookie
object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementCookieKey) ];
if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue;
if (object == 0 || CFGetTypeID(object) != CFNumberGetTypeID()) continue;
cookie = (IOHIDElementCookie) [object longValue];
//Get usage
object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsageKey) ];
if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue;
usage = [object longValue];
//Get usage page
object = [element valueForKey: (NSString*)CFSTR(kIOHIDElementUsagePageKey) ];
if (object == nil || ![object isKindOfClass:[NSNumber class]]) continue;
usagePage = [object longValue];
[allCookies addObject: [NSNumber numberWithInt:(int)cookie]];
}
} else {
return NO;
}
return YES;
}
- (BOOL) openDevice {
HRESULT result;
IOHIDOptionsType openMode = kIOHIDOptionsTypeNone;
if ([self isOpenInExclusiveMode]) openMode = kIOHIDOptionsTypeSeizeDevice;
IOReturn ioReturnValue = (*hidDeviceInterface)->open(hidDeviceInterface, openMode);
if (ioReturnValue == KERN_SUCCESS) {
queue = (*hidDeviceInterface)->allocQueue(hidDeviceInterface);
if (queue) {
result = (*queue)->create(queue, 0, 12); //depth: maximum number of elements in queue before oldest elements in queue begin to be lost.
int i=0;
for(i=0; i<[allCookies count]; i++) {
IOHIDElementCookie cookie = (IOHIDElementCookie)[[allCookies objectAtIndex:i] intValue];
(*queue)->addElement(queue, cookie, 0);
}
// add callback for async events
CFRunLoopSourceRef eventSource;
ioReturnValue = (*queue)->createAsyncEventSource(queue, &eventSource);
if (ioReturnValue == KERN_SUCCESS) {
ioReturnValue = (*queue)->setEventCallout(queue,QueueCallbackFunction, self, NULL);
if (ioReturnValue == KERN_SUCCESS) {
CFRunLoopAddSource(CFRunLoopGetCurrent(), eventSource, kCFRunLoopDefaultMode);
//start data delivery to queue
(*queue)->start(queue);
return YES;
} else {
NSLog(@"Error when setting event callout");
}
} else {
NSLog(@"Error when creating async event source");
}
} else {
NSLog(@"Error when opening device");
}
}
return NO;
}
@end
@implementation AppleRemoteApplicationDelegate
- (id) initWithApplicationDelegate: (id) delegate {
if (self = [super init]) {
applicationDelegate = [delegate retain];
}
return self;
}
- (void) dealloc {
[applicationDelegate release];
[super dealloc];
}
- (id) applicationDelegate {
return applicationDelegate;
}
- (void)applicationWillBecomeActive:(NSNotification *)aNotification {
if ([applicationDelegate respondsToSelector: @selector(applicationWillBecomeActive:)]) {
[applicationDelegate applicationWillBecomeActive: aNotification];
}
}
- (void)applicationDidBecomeActive:(NSNotification *)aNotification {
[[AppleRemote sharedRemote] setListeningToRemote: YES];
if ([applicationDelegate respondsToSelector: @selector(applicationDidBecomeActive:)]) {
[applicationDelegate applicationDidBecomeActive: aNotification];
}
}
- (void)applicationWillResignActive:(NSNotification *)aNotification {
[[AppleRemote sharedRemote] setListeningToRemote: NO];
if ([applicationDelegate respondsToSelector: @selector(applicationWillResignActive:)]) {
[applicationDelegate applicationWillResignActive: aNotification];
}
}
- (void)applicationDidResignActive:(NSNotification *)aNotification {
if ([applicationDelegate respondsToSelector: @selector(applicationDidResignActive:)]) {
[applicationDelegate applicationDidResignActive: aNotification];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
NSMethodSignature* signature = [super methodSignatureForSelector: aSelector];
if (signature == nil && applicationDelegate != nil) {
signature = [applicationDelegate methodSignatureForSelector: aSelector];
}
return signature;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
SEL aSelector = [invocation selector];
if (applicationDelegate==nil || [applicationDelegate respondsToSelector:aSelector]==NO) {
[super forwardInvocation: invocation];
return;
}
[invocation invokeWithTarget:applicationDelegate];
}
@end
/*****************************************************************************
* ImageAndTextCell.h: Helpful cell to display an image and a text.
* Borrowed from Apple's sample code for most part.
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
@interface ImageAndTextCell : NSTextFieldCell {
NSString *imageKeyPath;
id representedObject;
}
/* Will be set at creation time */
@property (copy) NSString * imageKeyPath;
/* Will be set through an outlineView delegate. Represent an object that respond
* to the imageKeyPath. Text is displayed through the usual super class
* @"value" bindings */
@property (retain) id representedObject;
@end
/*****************************************************************************
* ImageAndTextCell.h: Helpful cell to display an image and a text.
* Borrowed from Apple's sample code for most part.
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "ImageAndTextCell.h"
@implementation ImageAndTextCell
@synthesize imageKeyPath;
@synthesize representedObject;
- (id)init {
if (self = [super init]) {
[self setLineBreakMode:NSLineBreakByTruncatingTail];
[self setSelectable:YES];
}
return self;
}
- (void)dealloc {
[imageKeyPath release];
[super dealloc];
}
- (id)copyWithZone:(NSZone *)zone {
ImageAndTextCell *cell = (ImageAndTextCell *)[super copyWithZone:zone];
cell->imageKeyPath = [imageKeyPath copy];
cell->representedObject = [representedObject retain];
return cell;
}
- (NSImage *)cellImage
{
return imageKeyPath ? [[self representedObject] valueForKeyPath: imageKeyPath] : nil;
}
- (void)editWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject event:(NSEvent *)theEvent {
NSRect textFrame, imageFrame;
NSImage * image = [self cellImage];
NSDivideRect (aRect, &imageFrame, &textFrame, 6 + [image size].width, NSMinXEdge);
[super editWithFrame: textFrame inView: controlView editor:textObj delegate:anObject event: theEvent];
}
- (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(NSInteger)selStart length:(NSInteger)selLength {
NSRect textFrame, imageFrame;
NSImage * image = [self cellImage];
NSDivideRect (aRect, &imageFrame, &textFrame, 6 + [image size].width, NSMinXEdge);
[super selectWithFrame: textFrame inView: controlView editor:textObj delegate:anObject start:selStart length:selLength];
}
- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {
NSImage * image = [self cellImage];
if (image != nil) {
NSRect imageFrame;
NSSize imageSize = [image size];
NSDivideRect(cellFrame, &imageFrame, &cellFrame, 6 + imageSize.width, NSMinXEdge);
if ([self drawsBackground]) {
[[self backgroundColor] set];
NSRectFill(imageFrame);
}
imageFrame.origin.x += 3;
imageFrame.size = imageSize;
if ([controlView isFlipped])
imageFrame.origin.y += ceil((cellFrame.size.height + imageFrame.size.height) / 2);
else
imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2);
[image compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver];
}
[super drawWithFrame:cellFrame inView:controlView];
}
- (NSSize)cellSize {
NSImage * image = [self cellImage];
NSSize cellSize = [super cellSize];
cellSize.width += (image ? [image size].width : 0) + 6;
return cellSize;
}
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView {
NSPoint point = [controlView convertPoint:[event locationInWindow] fromView:nil];
NSImage * image = [self cellImage];
// If we have an image, we need to see if the user clicked on the image portion.
if (image != nil) {
// This code closely mimics drawWithFrame:inView:
NSSize imageSize = [image size];
NSRect imageFrame;
NSDivideRect(cellFrame, &imageFrame, &cellFrame, 6 + imageSize.width, NSMinXEdge);
imageFrame.origin.x += 3;
imageFrame.size = imageSize;
// If the point is in the image rect, then it is a content hit
if (NSMouseInRect(point, imageFrame, [controlView isFlipped])) {
// We consider this just a content area. It is not trackable, nor it it editable text. If it was, we would or in the additional items.
// By returning the correct parts, we allow NSTableView to correctly begin an edit when the text portion is clicked on.
return NSCellHitContentArea;
}
}
// At this point, the cellFrame has been modified to exclude the portion for the image. Let the superclass handle the hit testing at this point.
return [super hitTestForEvent:event inRect:cellFrame ofView:controlView];
}
@end
/*****************************************************************************
* VLCAppAdditions.m: Helpful additions to NS* classes
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
* Felix Kühne <fkuehne at videolan dot org>
* Jérôme Decoodt <djc at videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
/*****************************************************************************
* NSIndexPath (VLCAppAddition)
*****************************************************************************/
@interface NSIndexPath (VLCAppAddition)
- (NSIndexPath *)indexPathByRemovingFirstIndex;
- (NSUInteger)lastIndex;
@end
/*****************************************************************************
* NSArray (VLCAppAddition)
*****************************************************************************/
@interface NSArray (VLCAppAddition)
- (id)objectAtIndexPath:(NSIndexPath *)path withNodeKeyPath:(NSString *)nodeKeyPath;
@end
/*****************************************************************************
* NSView (VLCAppAdditions)
*****************************************************************************/
@interface NSView (VLCAppAdditions)
- (void)moveSubviewsToVisible;
@end
/*****************************************************************************
* VLCOneSplitView
*
* Missing functionality to a one-split view
*****************************************************************************/
@interface VLCOneSplitView : NSSplitView
{
}
- (float)sliderPosition;
- (void)setSliderPosition:(float)newPosition;
@end
/*****************************************************************************
* NSScreen (VLCAdditions)
*
* Missing extension to NSScreen
*****************************************************************************/
@interface NSScreen (VLCAdditions)
+ (NSScreen *)screenWithDisplayID: (CGDirectDisplayID)displayID;
- (BOOL)isMainScreen;
- (BOOL)isScreen: (NSScreen*)screen;
- (CGDirectDisplayID)displayID;
- (void)blackoutOtherScreens;
+ (void)unblackoutScreens;
@end
/*****************************************************************************
* VLCWindow
*
* Missing extension to NSWindow (Used only when needing setCanBecomeKeyWindow)
*****************************************************************************/
@interface VLCWindow : NSWindow
{
BOOL canBecomeKeyWindow;
BOOL isset_canBecomeKeyWindow;
}
- (void)setCanBecomeKeyWindow: (BOOL)canBecomeKey;
@end
/*****************************************************************************
* VLCImageCustomizedSlider
*
* Slider personalized by backgroundImage and knobImage
*****************************************************************************/
@interface VLCImageCustomizedSlider : NSSlider
{
NSImage * knobImage;
NSImage * backgroundImage;
}
@property (retain) NSImage * knobImage;
@property (retain) NSImage * backgroundImage;
- (void)drawKnobInRect: (NSRect)knobRect;
- (void)drawBackgroundInRect: (NSRect)knobRect;
- (void)drawRect: (NSRect)rect;
@end
/*****************************************************************************
* NSImageView (VLCAppAdditions)
*
* Make the image view move the window by mouse down by default
*****************************************************************************/
@interface NSImageView (VLCAppAdditions)
- (BOOL)mouseDownCanMoveWindow;
@end
/*****************************************************************************
* NSImage (VLCAppAdditions)
*
* Make the image view move the window by mouse down by default
*****************************************************************************/
@interface NSImage (VLCAppAdditions)
- (CGImageRef)CGImage;
@end
/*****************************************************************************
* VLCAppAdditions.m: Helpful additions to NS* classes
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
* Felix Kühne <fkuehne at videolan dot org>
* Jérôme Decoodt <djc at videolan dot org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCAppAdditions.h"
#import <QuartzCore/QuartzCore.h>
@implementation NSIndexPath (VLCAppAddition)
- (NSIndexPath *)indexPathByRemovingFirstIndex
{
if( [self length] <= 1 )
return [[[NSIndexPath alloc] init] autorelease];
NSIndexPath * ret;
NSUInteger * ints = malloc(sizeof(NSUInteger)*[self length]);
if( !ints ) return nil;
[self getIndexes:ints];
ret = [NSIndexPath indexPathWithIndexes:ints+1 length:[self length]-1];
free(ints);
return ret;
}
- (NSUInteger)lastIndex
{
if(![self length])
return 0;
return [self indexAtPosition:[self length]-1];
}
@end
@implementation NSArray (VLCAppAddition)
- (id)objectAtIndexPath:(NSIndexPath *)path withNodeKeyPath:(NSString *)nodeKeyPath
{
if( ![path length] || !nodeKeyPath )
return self;
id object = [self objectAtIndex:[path indexAtPosition:0]];
id subarray = [object valueForKeyPath:nodeKeyPath];
if([path length] == 1)
return subarray ? subarray : object;
if(!subarray)
return object;
return [subarray objectAtIndexPath:[path indexPathByRemovingFirstIndex] withNodeKeyPath:nodeKeyPath];
}
@end
@implementation NSView (VLCAppAdditions)
- (void)moveSubviewsToVisible
{
for(NSView * view in [self subviews])
{
if( ([view autoresizingMask] & NSViewHeightSizable) &&
!NSContainsRect([view frame], [self bounds]) )
{
NSRect newFrame = NSIntersectionRect( [self bounds], [view frame] );
if( !NSIsEmptyRect(newFrame) )
[view setFrame:NSIntersectionRect( [self bounds], [view frame] )];
}
}
}
@end
/* Split view that supports slider animation */
@implementation VLCOneSplitView
- (CGFloat)dividerThickness
{
return 1.;
}
- (void)drawDividerInRect:(NSRect)aRect
{
[self lockFocus];
[[NSColor blackColor] set];
NSRectFill(aRect);
[self unlockFocus];
}
- (float)sliderPosition
{
NSSize size = [[[self subviews] objectAtIndex:0] frame].size;
return [self isVertical] ? size.width : size.height;
}
- (void)setSliderPosition:(float)newPosition
{
[self setPosition:newPosition ofDividerAtIndex:0];
}
+ (id)defaultAnimationForKey:(NSString *)key
{
if([key isEqualToString:@"sliderPosition"])
{
return [CABasicAnimation animation];
}
return [super defaultAnimationForKey: key];
}
@end
/*****************************************************************************
* NSScreen (VLCAdditions)
*
* Missing extension to NSScreen
*****************************************************************************/
@implementation NSScreen (VLCAdditions)
static NSMutableArray *blackoutWindows = NULL;
+ (void)load
{
/* init our fake object attribute */
blackoutWindows = [[NSMutableArray alloc] initWithCapacity:1];
}
+ (NSScreen *)screenWithDisplayID: (CGDirectDisplayID)displayID
{
int i;
for( i = 0; i < [[NSScreen screens] count]; i++ )
{
NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
if([screen displayID] == displayID)
return screen;
}
return nil;
}
- (BOOL)isMainScreen
{
return ([self displayID] == [[[NSScreen screens] objectAtIndex:0] displayID]);
}
- (BOOL)isScreen: (NSScreen*)screen
{
return ([self displayID] == [screen displayID]);
}
- (CGDirectDisplayID)displayID
{
return (CGDirectDisplayID)_screenNumber;
}
- (void)blackoutOtherScreens
{
unsigned int i;
/* Free our previous blackout window (follow blackoutWindow alloc strategy) */
[blackoutWindows makeObjectsPerformSelector:@selector(close)];
[blackoutWindows removeAllObjects];
for(i = 0; i < [[NSScreen screens] count]; i++)
{
NSScreen *screen = [[NSScreen screens] objectAtIndex: i];
VLCWindow *blackoutWindow;
NSRect screen_rect;
if([self isScreen: screen])
continue;
screen_rect = [screen frame];
screen_rect.origin.x = screen_rect.origin.y = 0.0f;
/* blackoutWindow alloc strategy
- The NSMutableArray blackoutWindows has the blackoutWindow references
- blackoutOtherDisplays is responsible for alloc/releasing its Windows
*/
blackoutWindow = [[VLCWindow alloc] initWithContentRect: screen_rect styleMask: NSBorderlessWindowMask
backing: NSBackingStoreBuffered defer: NO screen: screen];
[blackoutWindow setBackgroundColor:[NSColor blackColor]];
[blackoutWindow setLevel: NSFloatingWindowLevel]; /* Disappear when Expose is triggered */
[blackoutWindow orderFront: self];
[blackoutWindows addObject: blackoutWindow];
[blackoutWindow release];
}
}
+ (void)unblackoutScreens
{
unsigned int i;
for(i = 0; i < [blackoutWindows count]; i++)
{
VLCWindow *blackoutWindow = [blackoutWindows objectAtIndex: i];
[blackoutWindow close];
}
}
@end
/*****************************************************************************
* VLCWindow
*
* Missing extension to NSWindow
*****************************************************************************/
@implementation VLCWindow
- (id)initWithContentRect:(NSRect)contentRect styleMask:(unsigned int)styleMask
backing:(NSBackingStoreType)backingType defer:(BOOL)flag
{
self = [super initWithContentRect:contentRect styleMask:styleMask backing:backingType defer:flag];
if( self )
isset_canBecomeKeyWindow = NO;
return self;
}
- (void)setCanBecomeKeyWindow: (BOOL)canBecomeKey
{
isset_canBecomeKeyWindow = YES;
canBecomeKeyWindow = canBecomeKey;
}
- (BOOL)canBecomeKeyWindow
{
if(isset_canBecomeKeyWindow)
return canBecomeKeyWindow;
return [super canBecomeKeyWindow];
}
@end
/*****************************************************************************
* VLCImageCustomizedSlider
*
* Slider personalized by backgroundImage and knobImage
*****************************************************************************/
@implementation VLCImageCustomizedSlider
@synthesize backgroundImage;
@synthesize knobImage;
- (id)initWithFrame:(NSRect)frame
{
if(self = [super initWithFrame:frame])
{
knobImage = nil;
backgroundImage = nil;
}
return self;
}
- (void)dealloc
{
[knobImage release];
[knobImage release];
[super dealloc];
}
- (void)drawKnobInRect:(NSRect) knobRect
{
NSRect imageRect;
imageRect.size = [self.knobImage size];
imageRect.origin.x = 0;
imageRect.origin.y = 0;
knobRect.origin.x += (knobRect.size.width - imageRect.size.width) / 2;
knobRect.origin.y += (knobRect.size.width - imageRect.size.width) / 2;
knobRect.size.width = imageRect.size.width;
knobRect.size.height = imageRect.size.height;
[self.knobImage drawInRect:knobRect fromRect:imageRect operation:NSCompositeSourceOver fraction:1];
}
- (void)drawBackgroundInRect:(NSRect) drawRect
{
NSRect imageRect = drawRect;
imageRect.origin.y += ([self.backgroundImage size].height - [self bounds].size.height ) / 2;
[self.backgroundImage drawInRect:drawRect fromRect:imageRect operation:NSCompositeSourceOver fraction:1];
}
- (void)drawRect:(NSRect)rect
{
/* Draw default to make sure the slider behaves correctly */
[[NSGraphicsContext currentContext] saveGraphicsState];
NSRectClip(NSZeroRect);
[super drawRect:rect];
[[NSGraphicsContext currentContext] restoreGraphicsState];
if( self.backgroundImage )
[self drawBackgroundInRect: rect];
if( self.knobImage )
{
NSRect knobRect = [[self cell] knobRectFlipped:NO];
[[[NSColor blackColor] colorWithAlphaComponent:0.6] set];
[self drawKnobInRect: knobRect];
}
}
@end
/*****************************************************************************
* NSImageView (VLCAppAdditions)
*
* Make the image view move the window by mouse down by default
*****************************************************************************/
@implementation NSImageView (VLCAppAdditions)
- (BOOL)mouseDownCanMoveWindow
{
return YES;
}
@end
/*****************************************************************************
* NSImage (VLCAppAdditions)
*
* Make the image view move the window by mouse down by default
*****************************************************************************/
@implementation NSImage (VLCAppAdditions)
- (CGImageRef)CGImage
{
return [[NSBitmapImageRep imageRepWithData:[NSBitmapImageRep TIFFRepresentationOfImageRepsInArray: [self representations]]] CGImage];
}
@end
/*****************************************************************************
* VLCAppBindings.m: Helpful addition code related to bindings uses
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <VLCKit/VLCKit.h>
/* We do implement some category functions,
* But we don't publicise them, as they should
* only be used with bindings. */
@interface VLCMediaDiscoverer (VLCAppBindings)
@end
@interface VLCMedia (VLCAppBindings)
@end
@interface VLCMediaPlayer (VLCAppBindings)
@end
/*****************************************************************************
* VLCAppBindings.m: Helpful addition code related to bindings uses
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCAppBindings.h"
/* This is globally a big hack to ease binding uses */
/******************************************************************************
* VLCMediaDiscoverer (CategoriesListBindings)
*/
@implementation VLCMediaDiscoverer (CategoriesListBindings)
+ (NSSet *)keyPathsForValuesAffectingCurrentlyFetchingItems
{
return [NSSet setWithObject:@"running"];
}
+ (NSSet *)keyPathsForValuesAffectingChildrenInCategoriesListForDetailView
{
return [NSSet setWithObject:@"discoveredMedia.flatAspect"];
}
/* General shortcuts */
- (BOOL)currentlyFetchingItems
{
return [self isRunning];
}
- (NSImage *)image
{
static NSImage * sdImage = nil;
if( !sdImage )
sdImage = [[NSImage imageNamed:@"applications-internet.png"] retain];
return sdImage;
}
/* CategoriesList specific bindings */
- (NSArray *)childrenInCategoriesList
{
return nil;
}
- (NSString *)descriptionInCategoriesList
{
return [self localizedName];
}
- (VLCMediaListAspect *)childrenInCategoriesListForDetailView
{
return [[self discoveredMedia] flatAspect];
}
- (BOOL)editableInCategoriesList
{
return NO;
}
- (BOOL)selectableInCategoriesList
{
return YES;
}
/* VideoView specific bindings */
- (NSArray *)childrenInVideoView
{
return [[[self discoveredMedia] flatAspect] valueForKeyPath:@"media"];
}
- (NSString *)descriptionInVideoView
{
return [self localizedName];
}
- (BOOL)isLeaf
{
return YES;
}
@end
/******************************************************************************
* VLCMedia (VLCAppBindings)
*/
@implementation VLCMedia (VLCAppBindings)
+ (NSSet *)keyPathsForValuesAffectingChildrenInCategoriesList
{
return [NSSet setWithObject:@"subitems.hierarchicalNodeAspect.media"];
}
+ (NSSet *)keyPathsForValuesAffectingDescriptionInCategoriesList
{
return [NSSet setWithObject:@"metaDictionary.title"];
}
+ (NSSet *)keyPathsForValuesAffectingChildrenInCategoriesListForDetailView
{
return [NSSet setWithObject:@"subitems.flatAspect"];
}
+ (NSSet *)keyPathsForValuesAffectingChildrenInDescriptionInVideoView
{
return [NSSet setWithObject:@"metaDictionary.title"];
}
+ (NSSet *)keyPathsForValuesAffectingStateAsImage
{
return [NSSet setWithObject:@"state"];
}
/* CategoriesList specific bindings */
- (NSArray *)childrenInCategoriesList
{
return [[[self subitems] hierarchicalNodeAspect] valueForKeyPath:@"media"];
}
- (void)setDescriptionInCategoriesList:(NSString *)description
{
NSLog(@"unimplemented: meta edition");
}
- (NSString *)descriptionInCategoriesList
{
return [[self metaDictionary] objectForKey:@"title"];
}
- (VLCMediaListAspect *)childrenInCategoriesListForDetailView
{
return [[self subitems] flatAspect];
}
- (BOOL)editableInCategoriesList
{
return YES;
}
- (BOOL)selectableInCategoriesList
{
return YES;
}
- (BOOL)currentlyFetchingItems
{
return NO;
}
- (NSImage *)image
{
static NSImage * playlistImage = nil;
if( !playlistImage )
playlistImage = [[NSImage imageNamed:@"type_playlist.png"] retain];
return playlistImage;
}
/* VideoView specific bindings */
- (NSArray *)childrenInVideoView
{
return [[[self subitems] flatAspect] valueForKeyPath:@"media"];
}
- (NSString *)descriptionInVideoView
{
return [[self metaDictionary] objectForKey:@"title"];
}
/* mediaListView specific bindings */
- (NSImage *)stateAsImage
{
static NSImage * playing = nil;
static NSImage * error = nil;
if(!playing)
playing = [[NSImage imageNamed:@"volume_high.png"] retain];
if(!error)
error = [[NSImage imageNamed:@"dialog-error.png"] retain];
if( [self state] == VLCMediaStatePlaying )
return playing;
else if( [self state] == VLCMediaStateBuffering )
return playing;
else if( [self state] == VLCMediaStateError )
return error;
return nil;
}
@end
@implementation VLCMediaPlayer (VLCAppBindings)
+ (NSSet *)keyPathsForValuesAffectingDescription
{
return [NSSet setWithObjects:@"playing", @"media", nil];
}
+ (NSSet *)keyPathsForValuesAffectingStateAsButtonImage
{
return [NSSet setWithObjects:@"state", @"playing", @"canPause", nil];
}
+ (NSSet *)keyPathsForValuesAffectingStateAsButtonAlternateImage
{
return [NSSet setWithObjects:@"state", @"playing", @"canPause", nil];
}
+ (NSSet *)keyPathsForValuesAffectingStateAsFullScreenButtonImage
{
return [NSSet setWithObjects:@"state", @"playing", @"canPause", nil];
}
+ (NSSet *)keyPathsForValuesAffectingStateAsFullScreenButtonAlternateImage
{
return [NSSet setWithObjects:@"state", @"playing", @"canPause", nil];
}
- (NSString *)description
{
if([self media])
return [self valueForKeyPath:@"media.metaDictionary.title"];
else
return @"VLC Media Player";
}
- (NSImage *)stateAsButtonImage
{
if([self state] == VLCMediaPlayerStatePlaying && [self canPause])
return [NSImage imageNamed:@"pause.png"];
else if( [self state] == VLCMediaPlayerStatePlaying )
return [NSImage imageNamed:@"stop.png"];
else
return [NSImage imageNamed:@"play.png"];
}
- (NSImage *)stateAsButtonAlternateImage
{
if([self state] == VLCMediaPlayerStatePlaying && [self canPause])
return [NSImage imageNamed:@"pause_blue.png"];
else if( [self state] == VLCMediaPlayerStatePlaying )
return [NSImage imageNamed:@"stop_blue.png"];
else
return [NSImage imageNamed:@"play_blue.png"];
}
- (NSImage *)stateAsFullScreenButtonImage
{
if([self state] == VLCMediaPlayerStatePlaying && [self canPause])
return [NSImage imageNamed:@"fs_pause.png"];
else if( [self state] == VLCMediaPlayerStatePlaying )
return [NSImage imageNamed:@"fs_stop.png"];
else
return [NSImage imageNamed:@"fs_play.png"];
}
- (NSImage *)stateAsFullScreenButtonAlternateImage
{
if([self state] == VLCMediaPlayerStatePlaying && [self canPause])
return [NSImage imageNamed:@"fs_pause_highlight.png"];
else if( [self state] == VLCMediaPlayerStatePlaying )
return [NSImage imageNamed:@"fs_stop_highlight.png"];
else
return [NSImage imageNamed:@"fs_play_highlight.png"];
}
@end
/*****************************************************************************
* VLCBrowsableVideoView.h: VideoView subclasses that allow fullscreen
* browsing
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <QuartzCore/QuartzCore.h>
#import <VLCKit/VLCKit.h>
#import "VLCAppAdditions.h"
@class VLCMainWindowController;
@class VLCMediaListLayer;
@interface VLCBrowsableVideoView : NSView {
BOOL menuDisplayed;
NSArray * itemsTree;
NSRange displayedItems;
NSInteger selectedIndex;
CALayer * selectionLayer;
CALayer * backLayer;
CALayer * menuLayer;
NSIndexPath * selectedPath;
NSString * nodeKeyPath;
NSString * contentKeyPath;
id selectedObject;
BOOL fullScreen;
/* Actions on non-node items*/
id target;
SEL action;
/* FullScreenTransition */
VLCWindow * fullScreenWindow;
NSViewAnimation * fullScreenAnim1;
NSViewAnimation * fullScreenAnim2;
NSView * tempFullScreenView;
IBOutlet VLCMainWindowController * mainWindowController;
VLCVideoLayer * videoLayer;
VLCMediaListLayer * mediaListLayer;
}
/* Binds an nsarray to that property. But don't forget the set the access keys. */
@property (retain) NSArray * itemsTree;
@property (copy) NSString * nodeKeyPath;
@property (copy) NSString * contentKeyPath;
@property (readonly, retain) id selectedObject;
@property (readwrite) BOOL fullScreen;
@property (readonly) BOOL hasVideo;
@property (readonly) VLCVideoLayer * videoLayer;
/* Set up a specific action to do, on items that don't have node.
* action first argument is the browsableVideoView. You can get the selected object,
* with -selectedObject */
@property (retain) id target;
@property SEL action;
- (void)toggleMenu;
- (void)displayMenu;
- (void)hideMenu;
- (IBAction)backToMediaListView:(id)sender;
@end
/*****************************************************************************
* VLCBrowsableVideoView.h: VideoView subclasses that allow fullScreen
* browsing
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007, 2009 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/* DisableScreenUpdates, SetSystemUIMode, ... */
#import <QuickTime/QuickTime.h>
#import "VLCBrowsableVideoView.h"
#import "VLCAppAdditions.h"
#import "VLCMediaListLayer.h"
#import "VLCMainWindowController.h"
/* TODO: We may want to clean up the private functions a bit... */
@interface VLCBrowsableVideoView ()
/* Property */
@property (readwrite, retain) id selectedObject;
@end
@interface VLCBrowsableVideoView (Private)
/* Methods */
+ (CAScrollLayer *)menuLayer;
+ (CALayer *)backLayer;
- (void)loadItemsAtIndexPath:(NSIndexPath *)path inLayer:(CALayer *)layer;
- (void)changeSelectedIndex:(NSInteger)i;
- (void)changeSelectedPath:(NSIndexPath *)newPath withSelectedIndex:(NSUInteger)newIndex;
- (void)displayEmptyView;
@end
@interface VLCBrowsableVideoView (FullScreenTransition)
- (void)hasEndedFullScreen;
- (void)hasBecomeFullScreen;
- (void)enterFullScreen:(NSScreen *)screen;
- (void)leaveFullScreen;
- (void)leaveFullScreenAndFadeOut: (BOOL)fadeout;
@end
#pragma mark -
/******************************************************************************
* VLCBrowsableVideoView
*/
@implementation VLCBrowsableVideoView
/* Property */
@synthesize nodeKeyPath;
@synthesize contentKeyPath;
@synthesize selectedObject;
@synthesize target;
@synthesize action;
@synthesize videoLayer;
- (NSArray *)itemsTree {
return itemsTree;
}
- (void)setItemsTree:(NSArray *)newItemsTree
{
[itemsTree release];
itemsTree = [newItemsTree retain];
[self changeSelectedPath:[[[NSIndexPath alloc] init] autorelease] withSelectedIndex:0];
}
- (BOOL)fullScreen
{
return [self isInFullScreenMode];
}
- (void)setFullScreen:(BOOL)newFullScreen
{
if( newFullScreen == self.fullScreen )
return;
if( newFullScreen )
{
[self enterFullScreenMode:[[self window] screen] withOptions:
[NSDictionary dictionaryWithObject: [NSNumber numberWithInt:1]
forKey: NSFullScreenModeWindowLevel]];
}
else
{
[self exitFullScreenModeWithOptions:nil];
}
}
- (BOOL)hasVideo
{
return videoLayer.hasVideo;
}
/* Binded to VideoLayer's hasVideo */
- (void)setHasVideo:(BOOL)hasVideo
{
if( hasVideo )
{
[CATransaction begin];
[videoLayer removeFromSuperlayer];
[self.layer addSublayer:videoLayer];
videoLayer.frame = [self layer].bounds;
[videoLayer setAutoresizingMask:kCALayerWidthSizable|kCALayerHeightSizable];
[mediaListLayer removeFromSuperlayer];
[CATransaction commit];
}
else
{
[CATransaction begin];
[mediaListLayer removeFromSuperlayer];
[self.layer addSublayer:mediaListLayer];
mediaListLayer.frame = [self layer].bounds;
[mediaListLayer setAutoresizingMask:kCALayerWidthSizable|kCALayerHeightSizable];
[videoLayer removeFromSuperlayer];
[CATransaction commit];
}
[[self layer] setNeedsDisplay];
[self setNeedsDisplay:YES];
}
/* Initializer */
- (void)awakeFromNib
{
// FIXME: do that in -initWithFrame:
[self setWantsLayer:YES];
menuDisplayed = NO;
displayedItems = NSMakeRange( -1, 0 );
selectedIndex = -1;
selectionLayer = backLayer = nil;
menuLayer = nil;
selectedPath = [[NSIndexPath alloc] init];
tempFullScreenView = [[NSView alloc] init];
fullScreen = NO;
videoLayer = [[VLCVideoLayer layer] retain];
[videoLayer addObserver:self forKeyPath:@"hasVideo" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
[videoLayer setDelegate:self];
NSAssert( mainWindowController, @"No mainWindowController" );
[mainWindowController.mediaPlayer setVideoLayer: videoLayer];
mediaListLayer = [[VLCMediaListLayer layerWithMediaArrayController:mainWindowController.mediaArrayController] retain];
[self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSURLPboardType, @"VLCMediaURLType", nil]];
[mainWindowController.mediaArrayController setSelectsInsertedObjects:YES];
[mainWindowController.mediaArrayController setAvoidsEmptySelection:YES];
[[self layer] addSublayer:mediaListLayer];
mediaListLayer.frame = [self layer].bounds;
[mediaListLayer setAutoresizingMask:kCALayerWidthSizable|kCALayerHeightSizable];
[[self layer] setNeedsDisplay];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if([keyPath isEqualToString:@"hasVideo"])
{
[self setHasVideo:[object hasVideo]];
return;
}
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
- (void)dealloc
{
/* Previously registered in */
[videoLayer removeObserver:self forKeyPath:@"hasVideo"];
[mediaListLayer release];
[videoLayer release];
[tempFullScreenView release];
[selectedPath release];
[super dealloc];
}
#pragma mark -
/* Drag and drop */
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
NSPasteboard *pboard;
pboard = [sender draggingPasteboard];
if ( [[pboard types] containsObject:NSFilenamesPboardType] &&
![mainWindowController.mediaArrayController.contentMediaList isReadOnly] )
{
self.layer.borderColor = CGColorCreateGenericGray(0.5, 0.5);
self.layer.cornerRadius = 10.f;
self.layer.borderWidth = 10.0;
return NSDragOperationCopy;
}
return NSDragOperationNone;
}
- (void)draggingEnded:(id < NSDraggingInfo >)sender
{
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:0.1] forKey:kCATransactionAnimationDuration];
self.layer.borderWidth = 0.;
[CATransaction commit];
[CATransaction begin];
[mainWindowController.mediaArrayController setFilterPredicate:nil];
[mainWindowController.mediaArrayController setSelectionIndex:[mainWindowController.mediaArrayController.contentMediaList count] - 1];
[CATransaction commit];
}
- (void)draggingExited:(id < NSDraggingInfo >)sender
{
self.layer.borderWidth = 0.;
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
NSPasteboard *pboard;
NSDragOperation sourceDragMask;
sourceDragMask = [sender draggingSourceOperationMask];
pboard = [sender draggingPasteboard];
if ( [[pboard types] containsObject:NSFilenamesPboardType] )
{
NSArray *files = [pboard propertyListForType:NSFilenamesPboardType];
VLCMediaList * mediaList = mainWindowController.mediaArrayController.contentMediaList;
if( [mediaList isReadOnly] )
return NO;
[CATransaction begin];
for( NSString * filePath in files )
[mediaList addMedia:[VLCMedia mediaWithPath:filePath]];
[CATransaction commit];
}
return YES;
}
- (void)showDrag
{
}
#pragma mark -
/* Hiding/Displaying the menu */
- (void)hideMenu
{
if( !menuDisplayed )
return; /* Nothing to do */
[menuLayer removeFromSuperlayer];
[selectionLayer removeFromSuperlayer];
[backLayer removeFromSuperlayer];
//[menuLayer autorelease]; /* Need gc for that */
//[selectionLayer autorelease];
//[backLayer autorelease];
selectionLayer = backLayer = nil;
menuLayer = nil;
menuDisplayed = NO;
[self setNeedsDisplay:YES];
}
- (void)displayMenu
{
if( menuDisplayed || !self.itemsTree )
return; /* Nothing to do */
if( !menuLayer )
{
CALayer * rootLayer = [self layer];
rootLayer.backgroundColor = CGColorGetConstantColor(kCGColorBlack);
rootLayer.layoutManager = [CAConstraintLayoutManager layoutManager];
menuLayer = [VLCBrowsableVideoView menuLayer];
[self loadItemsAtIndexPath: selectedPath inLayer: menuLayer];
}
if( !backLayer )
{
backLayer = [[VLCBrowsableVideoView backLayer] retain];
}
[[self layer] addSublayer:backLayer];
[[self layer] addSublayer:menuLayer];
[[self layer] setNeedsLayout];
[[self layer] setNeedsDisplay];
menuDisplayed = YES;
[self changeSelectedPath:selectedPath withSelectedIndex:selectedIndex];
}
- (void)toggleMenu
{
if( menuDisplayed )
[self hideMenu];
else
[self displayMenu];
}
- (IBAction)backToMediaListView:(id)sender
{
[mainWindowController.mediaPlayer stop];
[self setHasVideo: NO];
}
#pragma mark -
/* drawRect */
- (void)drawRect:(NSRect)rect
{
if( [self hasVideo] )
{
[[NSColor blackColor] set];
NSRectFill(rect);
return;
}
NSColor * topGradient = [NSColor colorWithCalibratedWhite:.0f alpha:1.0];
NSColor * bottomGradient = [NSColor colorWithCalibratedWhite:0.35f alpha:1.0];
NSGradient * gradient = [[NSGradient alloc] initWithColorsAndLocations:bottomGradient, 0.f, topGradient, 0.65f, topGradient, 1.f, nil];
[gradient drawInRect:self.bounds angle:100.0];
}
#pragma mark -
/* Event handling */
- (BOOL)acceptsFirstResponder
{
return YES;
}
-(void)moveUp:(id)sender
{
[self changeSelectedIndex:selectedIndex-1];
}
-(void)moveDown:(id)sender
{
[self changeSelectedIndex:selectedIndex+1];
}
- (void)mouseDown:(NSEvent *)theEvent
{
if([theEvent clickCount] == 1)
{
NSRect rect1 = [self bounds];
NSRect rect2 = [self bounds];
rect1.origin.x += [self bounds].size.width * 4./5.;
rect1.size.width /= 5.;
rect2.size.width /= 5.;
if(NSPointInRect([self convertPoint:[theEvent locationInWindow] fromView:nil], rect1))
{
[mainWindowController.mediaArrayController selectNext:self];
}
else if(NSPointInRect([self convertPoint:[theEvent locationInWindow] fromView:nil], rect2))
{
[mainWindowController.mediaArrayController selectPrevious:self];
}
return;
}
if([theEvent clickCount] == 2)
{
[mainWindowController mediaListViewItemDoubleClicked:self];
return;
}
if([theEvent clickCount] == 3)
{
self.fullScreen = !self.fullScreen;
}
}
- (void)keyDown:(NSEvent *)theEvent
{
if(([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == 13) && menuDisplayed)
{
[self changeSelectedPath:[selectedPath indexPathByAddingIndex:selectedIndex] withSelectedIndex:0];
}
else if([[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSLeftArrowFunctionKey && menuDisplayed)
{
if( [selectedPath length] > 0 )
[self changeSelectedPath:[selectedPath indexPathByRemovingLastIndex] withSelectedIndex:[selectedPath lastIndex]];
else
[self hideMenu];
}
else if(!menuDisplayed && [[theEvent charactersIgnoringModifiers] characterAtIndex:0] == NSRightArrowFunctionKey)
{
[self displayMenu];
}
else
[super keyDown: theEvent];
}
- (void)enterFullScreenMode:(NSScreen *)screen withOptions:(NSDictionary *)options
{
[self enterFullScreen: screen];
}
- (void)exitFullScreenModeWithOptions:(NSDictionary *)options
{
[self leaveFullScreen];
}
- (BOOL)isInFullScreenMode
{
return fullScreen;
}
@end
#pragma mark -
/******************************************************************************
* VLCBrowsableVideoView (Private)
*/
@implementation VLCBrowsableVideoView (Private)
+ (CAScrollLayer *)menuLayer
{
CAScrollLayer * layer = [CAScrollLayer layer];
layer.scrollMode = kCAScrollVertically;
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxY
relativeTo:@"superlayer" attribute:kCAConstraintMaxY]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxX
relativeTo:@"superlayer" attribute:kCAConstraintMaxX]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinX
relativeTo:@"superlayer" attribute:kCAConstraintMinX]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinY
relativeTo:@"superlayer" attribute:kCAConstraintMinY]];
return layer;
}
+ (CALayer *)backLayer
{
CALayer * layer = [CALayer layer];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxY
relativeTo:@"superlayer" attribute:kCAConstraintMaxY]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxX
relativeTo:@"superlayer" attribute:kCAConstraintMaxX]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinX
relativeTo:@"superlayer" attribute:kCAConstraintMinX]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinY
relativeTo:@"superlayer" attribute:kCAConstraintMinY]];
layer.opacity = 1.0;
layer.backgroundColor = CGColorCreateGenericRGB(0., 0., 0., .5);
return layer;
}
- (void)loadItemsAtIndexPath:(NSIndexPath *)path inLayer:(CALayer *)layer
{
const CGFloat height=70.0;
const CGFloat fontSize=48.0;
NSArray * items = [self.itemsTree objectAtIndexPath:path withNodeKeyPath:self.nodeKeyPath];
int i;
for( i = 0; i < [items count]; i++ )
{
CATextLayer *menuItemLayer=[CATextLayer layer];
id item = [items objectAtIndex: i];
menuItemLayer.string = self.contentKeyPath ? [item valueForKeyPath:self.contentKeyPath] : @"No content Key path set";
menuItemLayer.font = @"BankGothic-Light";
menuItemLayer.fontSize = fontSize;
menuItemLayer.foregroundColor = CGColorCreateGenericRGB(1.0,1.0,1.0,1.0);
menuItemLayer.shadowColor = CGColorCreateGenericRGB(0.0,0.0,0.0,1.0);
menuItemLayer.shadowOpacity = 0.7;
menuItemLayer.shadowRadius = 2.0;
menuItemLayer.frame = CGRectMake( 40., height*(-i) + layer.visibleRect.size.height, 500.0f,70.);
[layer addSublayer: menuItemLayer];
}
/* for(i=0; i < [[layer sublayers] count]; i++)
NSLog(@"%d, %@", i, [[[layer sublayers] objectAtIndex: i] string]);
NSLog(@"---");*/
}
- (void)changeSelectedIndex:(NSInteger)i
{
BOOL justCreatedSelectionLayer = NO;
if( !menuDisplayed )
{
selectedIndex = i;
return;
}
if( !selectionLayer )
{
justCreatedSelectionLayer = YES;
/* Rip-off from Apple's Sample code */
selectionLayer=[[CALayer layer] retain];
selectionLayer.borderWidth=2.0;
selectionLayer.borderColor=CGColorCreateGenericRGB(1.0f,1.0f,1.0f,1.0f);
selectionLayer.backgroundColor=CGColorCreateGenericRGB(.9f,1.0f,1.0f,.1f);
CIFilter *filter = [CIFilter filterWithName:@"CIBloom"];
[filter setDefaults];
[filter setValue:[NSNumber numberWithFloat:5.0] forKey:@"inputRadius"];
[filter setName:@"pulseFilter"];
[selectionLayer setFilters:[NSArray arrayWithObject:filter]];
CABasicAnimation* pulseAnimation = [CABasicAnimation animation];
pulseAnimation.keyPath = @"filters.pulseFilter.inputIntensity";
pulseAnimation.fromValue = [NSNumber numberWithFloat: 0.0];
pulseAnimation.toValue = [NSNumber numberWithFloat: 3.0];
pulseAnimation.duration = 2.0;
pulseAnimation.repeatCount = 1e100f;
pulseAnimation.autoreverses = YES;
pulseAnimation.timingFunction = [CAMediaTimingFunction functionWithName:
kCAMediaTimingFunctionEaseInEaseOut];
[selectionLayer addAnimation:pulseAnimation forKey:@"pulseAnimation"];
[[self layer] addSublayer:selectionLayer];
}
NSArray * items = [self.itemsTree objectAtIndexPath:selectedPath withNodeKeyPath:self.nodeKeyPath];
if( [items count] <= 0 )
return;
if( i >= [items count] ) i = [items count] - 1;
if( i < 0 ) i = 0;
CALayer * layer = [[menuLayer sublayers] objectAtIndex: i];
CGRect frame = layer.frame;
if( i == 0 )
{
frame.origin.y -= [self layer].bounds.size.height - frame.size.height;
frame.size.height = [self layer].bounds.size.height;
}
[(CAScrollLayer*)menuLayer scrollToRect:frame];
if( !justCreatedSelectionLayer ) /* Get around an artifact on first launch */
[CATransaction flush]; /* Make sure we get the "right" layer.frame */
frame = [[self layer] convertRect:layer.frame fromLayer:[layer superlayer]];
frame.size.width += 200.;
frame.origin.x -= 100.f;
selectionLayer.frame = frame;
selectionLayer.cornerRadius = selectionLayer.bounds.size.height / 2.;
selectedIndex = i;
}
- (void)changeSelectedPath:(NSIndexPath *)newPath withSelectedIndex:(NSUInteger)newIndex
{
if( menuDisplayed )
{
id object = [itemsTree objectAtIndexPath:newPath withNodeKeyPath:nodeKeyPath];
/* Make sure we are in a node */
if( ![object isKindOfClass:[NSArray class]] )
{
self.selectedObject = object;
if( !self.target || !self.action )
{
[NSException raise:@"VLCBrowsableVideoViewNoActionSpecified" format:@"*** Exception [%@]: No action specified.", [self class]];
return;
}
void (*method)(id, SEL, id) = (void (*)(id, SEL, id))[self.target methodForSelector: self.action];
method( self.target, self.action, self);
[self hideMenu];
return;
}
/* Make sure the node isn't empty */
if( ![object count] )
{
[self displayEmptyView];
}
else
{
CALayer * newMenuLayer = [VLCBrowsableVideoView menuLayer];
if( menuLayer )
newMenuLayer.bounds = menuLayer.bounds; /* Get around some artifacts */
[self loadItemsAtIndexPath:newPath inLayer:newMenuLayer];
if( menuLayer )
[[self layer] replaceSublayer:menuLayer with:newMenuLayer];
else
[[self layer] addSublayer:newMenuLayer];
//[menuLayer autorelease]; /* warn: we need gc for that */
menuLayer = [newMenuLayer retain];
}
}
[selectedPath release];
selectedPath = [newPath retain];
[self changeSelectedIndex:newIndex];
}
- (void)displayEmptyView
{
CALayer * layer = [CALayer layer];
layer.layoutManager = [CAConstraintLayoutManager layoutManager];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxY
relativeTo:@"superlayer" attribute:kCAConstraintMaxY]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxX
relativeTo:@"superlayer" attribute:kCAConstraintMaxX]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinX
relativeTo:@"superlayer" attribute:kCAConstraintMinX]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinY
relativeTo:@"superlayer" attribute:kCAConstraintMinY]];
CATextLayer *menuItemLayer=[CATextLayer layer];
menuItemLayer.string = @"Empty";
menuItemLayer.font = @"BankGothic-Light";
menuItemLayer.fontSize = 48.f;
menuItemLayer.foregroundColor = CGColorCreateGenericRGB(1.0,1.0,1.0,1.0);
menuItemLayer.shadowColor = CGColorCreateGenericRGB(0.0,0.0,0.0,1.0);
menuItemLayer.shadowOpacity = 0.7;
menuItemLayer.shadowRadius = 2.0;
[menuItemLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX
relativeTo:@"superlayer" attribute:kCAConstraintMidX]];
[menuItemLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY
relativeTo:@"superlayer" attribute:kCAConstraintMidY]];
[layer addSublayer:menuItemLayer];
if( menuLayer )
[[self layer] replaceSublayer:menuLayer with:layer];
else
[[self layer] addSublayer:layer];
[selectionLayer removeFromSuperlayer];
//[selectionLayer autorelease] /* need gc */
//[menuLayer autorelease] /* need gc */
menuLayer = layer;
selectionLayer = nil;
}
@end
#pragma mark -
@implementation VLCBrowsableVideoView (FullScreenTransition)
- (void)enterFullScreen:(NSScreen *)screen
{
NSMutableDictionary *dict1,*dict2;
NSRect screenRect;
NSRect aRect;
screenRect = [screen frame];
[NSCursor setHiddenUntilMouseMoves: YES];
/* Only create the o_fullScreen_window if we are not in the middle of the zooming animation */
if (!fullScreenWindow)
{
/* We can't change the styleMask of an already created NSWindow, so we create an other window, and do eye catching stuff */
aRect = [[self superview] convertRect: [self frame] toView: nil]; /* Convert to Window base coord */
aRect.origin.x += [[self window] frame].origin.x;
aRect.origin.y += [[self window] frame].origin.y;
fullScreenWindow = [[VLCWindow alloc] initWithContentRect:aRect styleMask: NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
[fullScreenWindow setBackgroundColor: [NSColor blackColor]];
[fullScreenWindow setCanBecomeKeyWindow: YES];
if (![[self window] isVisible] || [[self window] alphaValue] == 0.0 || [self isHiddenOrHasHiddenAncestor] )
{
/* We don't animate if we are not visible, instead we
* simply fade the display */
CGDisplayFadeReservationToken token;
[fullScreenWindow setFrame:screenRect display:NO];
CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token);
CGDisplayFade( token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0, 0, 0, YES );
if ([screen isMainScreen])
SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
[self retain];
[[self superview] replaceSubview:self with:tempFullScreenView];
[tempFullScreenView setFrame:[self frame]];
[fullScreenWindow setContentView:self];
[fullScreenWindow makeKeyAndOrderFront:self];
[self release];
[[tempFullScreenView window] orderOut: self];
CGDisplayFade( token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0, 0, 0, NO );
CGReleaseDisplayFadeReservation( token);
[self hasBecomeFullScreen];
return;
}
/* Make sure we don't see the o_view disappearing of the screen during this operation */
DisableScreenUpdates();
[self retain]; /* Removing from a view, make sure we won't be released */
/* Make sure our layer won't disappear */
CALayer * layer = [[self layer] retain];
id alayoutManager = layer.layoutManager;
[[self superview] replaceSubview:self with:tempFullScreenView];
[tempFullScreenView setFrame:[self frame]];
[fullScreenWindow setContentView:self];
[self setWantsLayer:YES];
[self setLayer:layer];
layer.layoutManager = alayoutManager;
[fullScreenWindow makeKeyAndOrderFront:self];
EnableScreenUpdates();
}
/* We are in fullScreen (and no animation is running) */
if (fullScreen)
{
/* Make sure we are hidden */
[[tempFullScreenView window] orderOut: self];
return;
}
if (fullScreenAnim1)
{
[fullScreenAnim1 stopAnimation];
[fullScreenAnim1 release];
}
if (fullScreenAnim2)
{
[fullScreenAnim2 stopAnimation];
[fullScreenAnim2 release];
}
if ([screen isMainScreen])
SetSystemUIMode( kUIModeAllHidden, kUIOptionAutoShowMenuBar);
dict1 = [[NSMutableDictionary alloc] initWithCapacity:2];
dict2 = [[NSMutableDictionary alloc] initWithCapacity:3];
[dict1 setObject:[tempFullScreenView window] forKey:NSViewAnimationTargetKey];
[dict1 setObject:NSViewAnimationFadeOutEffect forKey:NSViewAnimationEffectKey];
[dict2 setObject:fullScreenWindow forKey:NSViewAnimationTargetKey];
[dict2 setObject:[NSValue valueWithRect:[fullScreenWindow frame]] forKey:NSViewAnimationStartFrameKey];
[dict2 setObject:[NSValue valueWithRect:screenRect] forKey:NSViewAnimationEndFrameKey];
/* Strategy with NSAnimation allocation:
- Keep at most 2 animation at a time
- leaveFullScreen/enterFullScreen are the only responsible for releasing and alloc-ing
*/
fullScreenAnim1 = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict1, nil]];
fullScreenAnim2 = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict2, nil]];
[dict1 release];
[dict2 release];
[fullScreenAnim1 setAnimationBlockingMode: NSAnimationNonblocking];
[fullScreenAnim1 setDuration: 0.3];
[fullScreenAnim1 setFrameRate: 30];
[fullScreenAnim2 setAnimationBlockingMode: NSAnimationNonblocking];
[fullScreenAnim2 setDuration: 0.3];
[fullScreenAnim2 setFrameRate: 30];
[fullScreenAnim2 setDelegate: self];
[fullScreenAnim2 startWhenAnimation: fullScreenAnim1 reachesProgress: 1.0];
[fullScreenAnim1 startAnimation];
}
- (void)hasBecomeFullScreen
{
[fullScreenWindow makeFirstResponder: self];
[fullScreenWindow makeKeyWindow];
[fullScreenWindow setAcceptsMouseMovedEvents: TRUE];
[[tempFullScreenView window] orderOut: self];
[self willChangeValueForKey:@"fullScreen"];
fullScreen = YES;
[self didChangeValueForKey:@"fullScreen"];
}
- (void)leaveFullScreen
{
[self leaveFullScreenAndFadeOut: NO];
}
- (void)leaveFullScreenAndFadeOut: (BOOL)fadeout
{
NSMutableDictionary *dict1, *dict2;
NSRect frame;
[self willChangeValueForKey:@"fullScreen"];
fullScreen = NO;
[self didChangeValueForKey:@"fullScreen"];
/* Don't do anything if o_fullScreen_window is already closed */
if (!fullScreenWindow)
return;
if (fadeout || [tempFullScreenView isHiddenOrHasHiddenAncestor])
{
/* We don't animate if we are not visible, instead we
* simply fade the display */
CGDisplayFadeReservationToken token;
CGAcquireDisplayFadeReservation(kCGMaxDisplayReservationInterval, &token);
CGDisplayFade( token, 0.3, kCGDisplayBlendNormal, kCGDisplayBlendSolidColor, 0, 0, 0, YES );
SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
[self hasEndedFullScreen];
CGDisplayFade( token, 0.5, kCGDisplayBlendSolidColor, kCGDisplayBlendNormal, 0, 0, 0, NO );
CGReleaseDisplayFadeReservation( token);
return;
}
[[tempFullScreenView window] setAlphaValue: 0.0];
[[tempFullScreenView window] orderFront: self];
SetSystemUIMode( kUIModeNormal, kUIOptionAutoShowMenuBar);
if (fullScreenAnim1)
{
[fullScreenAnim1 stopAnimation];
[fullScreenAnim1 release];
}
if (fullScreenAnim2)
{
[fullScreenAnim2 stopAnimation];
[fullScreenAnim2 release];
}
frame = [[tempFullScreenView superview] convertRect: [tempFullScreenView frame] toView: nil]; /* Convert to Window base coord */
frame.origin.x += [tempFullScreenView window].frame.origin.x;
frame.origin.y += [tempFullScreenView window].frame.origin.y;
dict2 = [[NSMutableDictionary alloc] initWithCapacity:2];
[dict2 setObject:[tempFullScreenView window] forKey:NSViewAnimationTargetKey];
[dict2 setObject:NSViewAnimationFadeInEffect forKey:NSViewAnimationEffectKey];
fullScreenAnim2 = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict2, nil]];
[dict2 release];
[fullScreenAnim2 setAnimationBlockingMode: NSAnimationNonblocking];
[fullScreenAnim2 setDuration: 0.3];
[fullScreenAnim2 setFrameRate: 30];
[fullScreenAnim2 setDelegate: self];
dict1 = [[NSMutableDictionary alloc] initWithCapacity:3];
[dict1 setObject:fullScreenWindow forKey:NSViewAnimationTargetKey];
[dict1 setObject:[NSValue valueWithRect:[fullScreenWindow frame]] forKey:NSViewAnimationStartFrameKey];
[dict1 setObject:[NSValue valueWithRect:frame] forKey:NSViewAnimationEndFrameKey];
fullScreenAnim1 = [[NSViewAnimation alloc] initWithViewAnimations:[NSArray arrayWithObjects:dict1, nil]];
[dict1 release];
[fullScreenAnim1 setAnimationBlockingMode: NSAnimationNonblocking];
[fullScreenAnim1 setDuration: 0.2];
[fullScreenAnim1 setFrameRate: 30];
[fullScreenAnim2 startWhenAnimation: fullScreenAnim1 reachesProgress: 1.0];
/* Make sure o_fullScreen_window is the frontmost window */
[fullScreenWindow orderFront: self];
[fullScreenAnim1 startAnimation];
}
- (void)hasEndedFullScreen
{
/* This function is private and should be only triggered at the end of the fullScreen change animation */
/* Make sure we don't see the o_view disappearing of the screen during this operation */
DisableScreenUpdates();
[self retain];
/* Make sure we don't loose the layer */
CALayer * layer = [[self layer] retain];
id alayoutManager = layer.layoutManager;
[self removeFromSuperviewWithoutNeedingDisplay];
[[tempFullScreenView superview] replaceSubview:tempFullScreenView with:self];
[self release];
[self setWantsLayer:YES];
[self setLayer:layer];
layer.layoutManager = alayoutManager;
[self setFrame:[tempFullScreenView frame]];
[[self window] makeFirstResponder: self];
if ([[self window] isVisible])
[[self window] makeKeyAndOrderFront:self];
[fullScreenWindow orderOut: self];
EnableScreenUpdates();
[fullScreenWindow release];
fullScreenWindow = nil;
}
- (void)animationDidEnd:(NSAnimation*)animation
{
NSArray *viewAnimations;
if ([animation currentValue] < 1.0)
return;
/* FullScreen ended or started (we are a delegate only for leaveFullScreen's/enterFullscren's anim2) */
viewAnimations = [fullScreenAnim2 viewAnimations];
if ([viewAnimations count] >=1 &&
[[[viewAnimations objectAtIndex: 0] objectForKey: NSViewAnimationEffectKey] isEqualToString:NSViewAnimationFadeInEffect])
{
/* FullScreen ended */
[self hasEndedFullScreen];
}
else
{
/* FullScreen started */
[self hasBecomeFullScreen];
}
}
@end
/*****************************************************************************
* VLCController.h: VLC.app main controller
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <VLCKit/VLCKit.h>
@class VLCMainWindow;
@interface VLCController : NSObject
{
NSArray * categories;
}
@property (readonly, retain) NSArray * categories;
- (void)newMainWindow:(id)sender;
- (void)addPlaylist:(id)sender;
@end
/*****************************************************************************
* VLCController.m: VLC.app main controller
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <VLCKit/VLCKit.h>
#import "VLCController.h"
#import "VLCAppAdditions.h"
#import "VLCValueTransformer.h"
@interface VLCController ()
@property (readwrite,retain) NSArray * categories;
@end
/******************************************************************************
* VLCBrowsableVideoView
*/
@implementation VLCController
@synthesize categories;
- (void)awakeFromNib
{
/***********************************
* Register our bindings value transformer
*/
VLCFloat10000FoldTransformer *float100fold;
float100fold = [[[VLCFloat10000FoldTransformer alloc] init] autorelease];
[NSValueTransformer setValueTransformer:(id)float100fold forName:@"Float10000FoldTransformer"];
VLCNonNilAsBoolTransformer *nonNilAsBool;
nonNilAsBool = [[[VLCNonNilAsBoolTransformer alloc] init] autorelease];
[NSValueTransformer setValueTransformer:(id)nonNilAsBool forName:@"NonNilAsBoolTransformer"];
VLCURLToRepresentedFileNameTransformer *urlToRepresentedFileName;
urlToRepresentedFileName = [[[VLCURLToRepresentedFileNameTransformer alloc] init] autorelease];
[NSValueTransformer setValueTransformer:(id)urlToRepresentedFileName forName:@"URLToRepresentedFileNameTransformer"];
VLCSelectionIndexToDescriptionTransformer *indexToDescription;
indexToDescription = [[[VLCSelectionIndexToDescriptionTransformer alloc] init] autorelease];
[NSValueTransformer setValueTransformer:(id)indexToDescription forName:@"SelectionIndexToDescriptionTransformer"];
/***********************************
* categories: Main content
*/
NSArray * mediaDiscoverers = [NSArray arrayWithObjects:
[[[VLCMediaDiscoverer alloc] initWithName:@"shoutcasttv"] autorelease],
[[[VLCMediaDiscoverer alloc] initWithName:@"shoutcast"] autorelease],
[[[VLCMediaDiscoverer alloc] initWithName:@"sap"] autorelease],
[[[VLCMediaDiscoverer alloc] initWithName:@"freebox"] autorelease], nil];
self.categories = [NSArray arrayWithObjects:
[NSMutableDictionary dictionaryWithObjectsAndKeys:
[@"Service Discovery" uppercaseString], @"descriptionInCategoriesList",
@"Service Discovery", @"descriptionInVideoView",
[NSNumber numberWithBool:NO], @"selectableInCategoriesList",
mediaDiscoverers, @"childrenInCategoriesList",
mediaDiscoverers, @"childrenInVideoView",
nil],
[VLCMedia mediaAsNodeWithName:@"Playlist"],
nil];
/* Execution will continue in applicationDidFinishLaunching */
[NSApp setDelegate:self];
}
- (void)newMainWindow:(id)sender
{
if (![NSBundle loadNibNamed:@"MainWindow" owner:self])
{
NSLog(@"Warning! Could not load MainWindow file.\n");
}
/* We are done. Should be on screen if Visible at launch time is checked */
}
- (void)addPlaylist:(id)sender
{
// TODO
NSLog(@"unimplemented!");
}
@end
@implementation VLCController (NSAppDelegate)
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[self newMainWindow: self];
}
@end
/*****************************************************************************
* VLCExceptionHandler.h: VLCExceptionHandler implementation
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
@interface VLCExceptionHandler : NSObject {
}
- (void)printStackTrace:(NSException *)e;
@end
/*****************************************************************************
* VLCExceptionHandler.m: VLCExceptionHandler implementation
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCExceptionHandler.h"
#import <ExceptionHandling/ExceptionHandling.h>
@implementation VLCExceptionHandler
+ (void)load
{
[[NSExceptionHandler defaultExceptionHandler] setDelegate:[[VLCExceptionHandler alloc] init]];
[[NSExceptionHandler defaultExceptionHandler] setExceptionHandlingMask:
0xffff /* Catch all */ ];
[[NSExceptionHandler defaultExceptionHandler] setExceptionHangingMask:
NSHangOnUncaughtExceptionMask|
NSHangOnUncaughtSystemExceptionMask|
NSHangOnUncaughtRuntimeErrorMask|
NSHangOnTopLevelExceptionMask|
NSHangOnOtherExceptionMask];
}
/* From Apple's guide on exception */
- (BOOL)exceptionHandler:(NSExceptionHandler *)sender shouldLogException:(NSException *)exception mask:(unsigned int)aMask
{
[self printStackTrace:exception];
NSLog(@"*** Exception Handled! %@: %@", [exception name], [exception reason]);
int ret = NSRunCriticalAlertPanel(@"Exception not handled!",
[NSString stringWithFormat:@"%@: %@\n\nBack trace has been printed to Console.\n\nWe will now wait for debugger connection...\n",
[exception name], [exception reason]],
@"Quit", @"Wait Debugger", nil);
if( ret == NSOKButton )
{
[NSApp terminate:self];
}
return YES;
}
- (void)printStackTrace:(NSException *)e
{
NSString *stack = [[e userInfo] objectForKey:NSStackTraceKey];
if (!stack)
{
NSLog(@"No stack trace available.");
return;
}
NSTask *ls = [[NSTask alloc] init];
NSString *pid = [[NSNumber numberWithInt:[[NSProcessInfo processInfo] processIdentifier]] stringValue];
NSMutableArray *args = [NSMutableArray arrayWithCapacity:20];
[args addObject:@"-p"];
[args addObject:pid];
[args addObjectsFromArray:[stack componentsSeparatedByString:@" "]];
/* Note: function addresses are separated by double spaces, not a single space. */
[ls setLaunchPath:@"/usr/bin/atos"];
[ls setArguments:args];
[ls launch];
[ls release];
}
@end
/*****************************************************************************
* VLCFullScreenControllerWindow.m: class that allow media controlling in
* fullscreen (with the mouse)
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <VLCKit/VLCKit.h>
#import "VLCAppAdditions.h"
#import "VLCMainWindowController.h"
@interface VLCFullScreenControllerWindow : NSPanel
{
/* IBOutlets */
IBOutlet VLCImageCustomizedSlider * volumeSlider;
IBOutlet VLCImageCustomizedSlider * mediaPositionSlider;
IBOutlet NSButton * mediaPlayerForwardNextButton;
IBOutlet NSButton * mediaPlayerBackwardPrevButton;
IBOutlet NSButton * mediaPlayerPlayPauseStopButton;
IBOutlet id fillScreenButton;
IBOutlet id fullScreenButton;
IBOutlet NSTextField * mediaReadingProgressText;
IBOutlet NSTextField * mediaDescriptionText;
NSTimer * hideWindowTimer;
NSTrackingArea * videoViewTrackingArea;
BOOL active;
/* Owner */
IBOutlet VLCMainWindowController * mainWindowController;
/* Draging the window using its content */
NSPoint mouseClic;
}
@end
/*****************************************************************************
* VLCFullScreenControllerWindow.m: class that allow media controlling in
* fullscreen (with the mouse)
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Jérôme Decoodt <djc at videolan dot org>
* Felix Kühne <fkuehne at videolan dot org>
* Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCFullScreenControllerWindow.h"
@interface VLCFullScreenControllerWindow (Private)
- (void)hide;
- (void)show;
- (void)updateTrackingRect;
@end
/*****************************************************************************
* @implementation VLCFullScreenControllerWindow
*/
@implementation VLCFullScreenControllerWindow
/* We override this initializer so we can set the NSBorderlessWindowMask styleMask, and set a few other important settings */
- (id)initWithContentRect:(NSRect)contentRect
styleMask:(unsigned int)aStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag
{
if( self = [super initWithContentRect:contentRect styleMask:NSTexturedBackgroundWindowMask backing:bufferingType defer:flag] )
{
[self setOpaque:NO];
[self setHasShadow: NO];
[self setBackgroundColor:[NSColor clearColor]];
/* let the window sit on top of everything else and start out completely transparent */
[self setLevel:NSFloatingWindowLevel];
[self center];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[hideWindowTimer invalidate];
[hideWindowTimer release];
[videoViewTrackingArea release];
[super dealloc];
}
- (void)awakeFromNib
{
hideWindowTimer = nil;
videoViewTrackingArea = nil;
[self setMovableByWindowBackground:YES];
/* Make sure we'll detect when to close the window, see animationDidStop:finished: */
CAAnimation *alphaValueAnimation = [CABasicAnimation animation];
[alphaValueAnimation setDelegate:self];
[self setAnimations:[NSDictionary dictionaryWithObject:alphaValueAnimation forKey:@"alphaValue"]];
hideWindowTimer = nil;
/* WindowView setup */
[[mainWindowController.videoView window] setAcceptsMouseMovedEvents:YES];
[[mainWindowController.videoView window] makeFirstResponder:mainWindowController.videoView];
[mainWindowController.videoView setPostsBoundsChangedNotifications: YES];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoViewDidChangeBounds:) name:NSViewBoundsDidChangeNotification object:(id)mainWindowController.videoView];
/* Make sure we can know when the mouse is inside us */
[[self contentView] addTrackingRect:[[self contentView] bounds] owner:self userData:nil assumeInside:NO];
/* Bindings connection */
/* Sound */
[volumeSlider setKnobImage:[NSImage imageNamed:@"fs_volume_slider_knob_highlight.png"]];
[volumeSlider setBackgroundImage:[NSImage imageNamed:@"fs_volume_slider_bar.png"]];
[volumeSlider setNeedsDisplay:YES];
[volumeSlider bind:@"value" toObject:[VLCLibrary sharedLibrary] withKeyPath:@"audio.volume" options: nil];
/* media position */
[mediaPositionSlider setKnobImage:[NSImage imageNamed:@"fs_time_slider_knob.png"]];
[mediaPositionSlider setBackgroundImage:[NSImage imageNamed:@"fs_time_slider.png"]];
[mediaPositionSlider setNeedsDisplay:YES];
[mediaPositionSlider bind:@"enabled" toObject:mainWindowController.mediaPlayer withKeyPath:@"media" options: [NSDictionary dictionaryWithObject:@"NonNilAsBoolTransformer" forKey:NSValueTransformerNameBindingOption]];
[mediaPositionSlider bind:@"enabled2" toObject:mainWindowController.mediaPlayer withKeyPath:@"seekable" options: nil];
[mediaPositionSlider bind:@"value" toObject:mainWindowController.mediaPlayer withKeyPath:@"position" options:
[NSDictionary dictionaryWithObjectsAndKeys:@"Float10000FoldTransformer", NSValueTransformerNameBindingOption,
[NSNumber numberWithBool:NO], NSConditionallySetsEnabledBindingOption, nil ]];
[fillScreenButton bind:@"value" toObject:mainWindowController.videoView withKeyPath:@"videoLayer.fillScreen" options: nil];
[fullScreenButton bind:@"value" toObject:mainWindowController.videoView withKeyPath:@"fullScreen" options: nil];
[mediaReadingProgressText bind:@"value" toObject:mainWindowController.mediaPlayer withKeyPath:@"time.stringValue" options: nil];
[mediaDescriptionText bind:@"value" toObject:mainWindowController.mediaPlayer withKeyPath:@"description" options: nil];
/* mainWindowController.mediaPlayer */
[mediaPlayerPlayPauseStopButton bind:@"enabled" toObject:mainWindowController.mediaPlayer withKeyPath:@"media" options: [NSDictionary dictionaryWithObject:@"NonNilAsBoolTransformer" forKey:NSValueTransformerNameBindingOption]];
[mediaPlayerPlayPauseStopButton bind:@"state" toObject:mainWindowController.mediaPlayer withKeyPath:@"playing" options: nil];
[mediaPlayerPlayPauseStopButton bind:@"alternateImage" toObject:mainWindowController.mediaPlayer withKeyPath:@"stateAsFullScreenButtonAlternateImage" options: nil];
[mediaPlayerPlayPauseStopButton bind:@"image" toObject:mainWindowController.mediaPlayer withKeyPath:@"stateAsFullScreenButtonImage" options: nil];
[mediaPlayerBackwardPrevButton bind:@"enabled" toObject:mainWindowController.mediaPlayer withKeyPath:@"playing" options: nil];
[mediaPlayerForwardNextButton bind:@"enabled" toObject:mainWindowController.mediaPlayer withKeyPath:@"playing" options: nil];
[mediaPlayerForwardNextButton setTarget:mainWindowController.mediaPlayer];
[mediaPlayerForwardNextButton setAction:@selector(fastForward)];
[mediaPlayerBackwardPrevButton setTarget:mainWindowController.mediaPlayer];
[mediaPlayerBackwardPrevButton setAction:@selector(rewind)];
[mediaPlayerPlayPauseStopButton setTarget:mainWindowController.mediaPlayer];
[mediaPlayerPlayPauseStopButton setAction:@selector(pause)];
[self bind:@"fullScreen" toObject:mainWindowController.videoView withKeyPath:@"fullScreen" options: nil];
active = NO;
}
- (BOOL)fullScreen
{
/* Only to comply to KVC */
return active;
}
- (void)setFullScreen:(BOOL)fullScreen
{
if(fullScreen)
{
active = YES;
[self show];
}
else
{
[self hide];
active = NO;
}
}
-(void)center
{
/* centre the panel in the lower third of the screen */
NSPoint theCoordinate;
NSRect theScreensFrame;
NSRect theWindowsFrame;
theScreensFrame = [[self screen] frame];
theWindowsFrame = [self frame];
theCoordinate.x = (theScreensFrame.size.width - theWindowsFrame.size.width) / 2 + theScreensFrame.origin.x;
theCoordinate.y = (theScreensFrame.size.height / 3) - theWindowsFrame.size.height + theScreensFrame.origin.y;
[self setFrameTopLeftPoint: theCoordinate];
}
@end
/*****************************************************************************
* @implementation VLCFullScreenControllerWindow (Private)
*/
@implementation VLCFullScreenControllerWindow (Private)
- (void)show
{
if(![self isVisible])
self.alphaValue = 0.0;
if( !NSPointInRect([NSEvent mouseLocation],[self frame]) )
{
[hideWindowTimer invalidate];
[hideWindowTimer release];
hideWindowTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(hide) userInfo:nil repeats:NO] retain];
}
[self orderFront:self];
[self.animator setAlphaValue:1.0];
}
- (void)hide
{
[hideWindowTimer invalidate];
[hideWindowTimer release];
hideWindowTimer = nil;
if ([self isVisible])
{
[self.animator setAlphaValue:0.0];
[NSCursor setHiddenUntilMouseMoves:YES];
}
[self updateTrackingRect];
}
- (void)updateTrackingRect
{
VLCBrowsableVideoView * videoView = mainWindowController.videoView;
if( videoViewTrackingArea )
{
[videoView removeTrackingArea:videoViewTrackingArea];
[videoViewTrackingArea release];
}
videoViewTrackingArea = [[NSTrackingArea alloc] initWithRect:[videoView bounds] options:NSTrackingMouseMoved|NSTrackingActiveAlways|NSTrackingAssumeInside|NSTrackingEnabledDuringMouseDrag owner:self userInfo:nil];
[videoView addTrackingArea:videoViewTrackingArea];
}
@end
/*****************************************************************************
* @implementation VLCFullScreenControllerWindow (NSAnimationDelegate)
*/
@implementation VLCFullScreenControllerWindow (NSAnimationDelegate)
- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag
{
if( self.alphaValue == 0.0 )
[self orderOut:self];
}
@end
/*****************************************************************************
* @implementation VLCFullScreenControllerWindow (NSTrackingRectCallbacksInVideoView)
*/
@implementation VLCFullScreenControllerWindow (NSTrackingRectCallbacks)
- (void)mouseMoved:(NSEvent *)theEvent
{
if([theEvent window] != self)
{
if( active )
[self show];
}
}
- (void)mouseEntered:(NSEvent *)theEvent
{
if([theEvent window] == self)
{
[hideWindowTimer invalidate];
[hideWindowTimer release];
hideWindowTimer = nil;
}
}
- (void)mouseExited:(NSEvent *)theEvent
{
if([theEvent window] == self)
{
[hideWindowTimer invalidate];
[hideWindowTimer release];
hideWindowTimer = [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(hide) userInfo:nil repeats:NO] retain];
}
else
{
if( active )
[self hide];
}
}
- (void)cursorUpdate:(NSEvent *)event
{
}
@end
/*****************************************************************************
* @implementation VLCFullScreenControllerWindow (VideoViewBoundsChanges)
*/
@implementation VLCFullScreenControllerWindow (VideoViewBoundsChanges)
- (void)videoViewDidChangeBounds:(NSNotification *)theNotification
{
[self updateTrackingRect];
}
@end
/*****************************************************************************
* VLCMainWindow.h: VLCMainWindow implementation
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
@interface VLCMainWindow : NSWindow {
}
@end
/*****************************************************************************
* VLCMainWindow.m: VLCMainWindow implementation
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCMainWindow.h"
/******************************************************************************
* VLCMainWindow
*/
@implementation VLCMainWindow
@end
/*****************************************************************************
* VLCMainWindowController.h: VLCMainWindowController implementation
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import "VLCController.h"
#import "VLCMediaArrayController.h"
#import "VLCAppAdditions.h"
#import "VLCBrowsableVideoView.h"
#import "VLCMainWindow.h"
@interface VLCMainWindowController : NSWindowController
{
IBOutlet VLCOneSplitView * mainSplitView;
/* Media List */
IBOutlet NSTableView * mediaListView;
/* Categories List */
IBOutlet NSOutlineView * categoriesListView;
IBOutlet NSButton * addPlaylistButton;
IBOutlet NSButton * removePlaylistButton;
/* Toolbar control buttons */
IBOutlet NSButton * mediaPlayerForwardNextButton;
IBOutlet NSButton * mediaPlayerBackwardPrevButton;
IBOutlet NSButton * mediaPlayerPlayPauseStopButton;
/* Toolbar */
IBOutlet NSView * toolbarMediaAudioVolume;
IBOutlet NSView * toolbarMediaDescription;
IBOutlet NSView * toolbarMediaControl;
/* Video */
IBOutlet VLCBrowsableVideoView * videoView;
/* Controllers */
NSTreeController * categoriesTreeController;
IBOutlet VLCMediaArrayController * mediaArrayController;
IBOutlet VLCMediaPlayer * mediaPlayer;
IBOutlet VLCController * controller; /* This is a VLCController binded to the File's Owner of the nib */
/* States */
float navigatorViewWidth;
}
@property BOOL navigatorViewVisible;
- (void)setNavigatorViewVisible:(BOOL)wantsVisible animate:(BOOL)animate;
@property (readonly) VLCMediaPlayer * mediaPlayer;
@property (readonly) VLCBrowsableVideoView * videoView;
@property (readonly) VLCMediaArrayController * mediaArrayController;
@property (readonly) NSTreeController * categoriesTreeController;
- (IBAction)mediaListViewItemDoubleClicked:(id)sender;
- (void)videoViewItemClicked:(id)sender;
@end
/*****************************************************************************
* VLCMainWindowController.m: VLCMainWindowController implementation
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCMainWindowController.h"
#import "VLCAppAdditions.h"
#import "ImageAndTextCell.h"
/******************************************************************************
* @implementation VLCMainWindowController
*/
@implementation VLCMainWindowController
@synthesize mediaPlayer;
@synthesize videoView;
@synthesize mediaArrayController;
@synthesize categoriesTreeController;
- (void)awakeFromNib
{
NSTableColumn * tableColumn;
/***********************************
* Init the media player
*/
NSAssert( mediaPlayer, @"No mediaPlayer" );
[self willChangeValueForKey:@"categoriesTreeController"];
categoriesTreeController = [[NSTreeController alloc] init];
[self didChangeValueForKey:@"categoriesTreeController"];
/***********************************
* CategoriesList OutlineView content
*/
/* categoriesTreeController */
NSAssert( categoriesTreeController, @"No categoriesTreeController" );
NSAssert( categoriesListView, @"No categoriesListView" );
NSAssert( controller, @"No controller" );
[categoriesTreeController setContent:controller.categories];
//[categoriesTreeController bind:@"content" toObject:controller withKeyPath:@"categories" options:nil];
[categoriesTreeController setChildrenKeyPath:@"childrenInCategoriesList"];
/* Bind the "name" table column */
tableColumn = [categoriesListView tableColumnWithIdentifier:@"name"];
[tableColumn bind:@"value" toObject:categoriesTreeController withKeyPath:@"arrangedObjects.descriptionInCategoriesList" options:nil];
/* Use an ImageAndTextCell in the "name" table column */
ImageAndTextCell * cell = [[ImageAndTextCell alloc] init];
[cell setFont:[[tableColumn dataCell] font]];
[cell setImageKeyPath:@"image"];
[tableColumn setDataCell: cell];
/* Other setup */
[categoriesListView setIndentationMarkerFollowsCell:YES];
[categoriesListView setAutoresizesOutlineColumn:NO];
[categoriesListView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList];
[categoriesListView setDelegate:self];
[categoriesListView registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSURLPboardType, @"VLCMediaURLType", nil]];
[categoriesListView setDataSource: self];
/***********************************
* mediaListView setup
*/
/* 1- Drag and drop */
NSAssert( mediaArrayController, @"No mediaArrayController" );
NSAssert( mediaListView, @"No mediaListView" );
[mediaListView registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSURLPboardType, nil]];
[mediaListView setDataSource:mediaArrayController];
/* 3- binding for "title" column */
tableColumn = [mediaListView tableColumnWithIdentifier:@"title"];
[tableColumn bind:@"value" toObject: mediaArrayController withKeyPath:@"arrangedObjects.metaDictionary.title" options:nil];
/* 2- Double click */
[mediaListView setTarget:self];
[mediaListView setDoubleAction:@selector(mediaListViewItemDoubleClicked:)];
/* 4- binding for "state" column */
tableColumn = [mediaListView tableColumnWithIdentifier:@"state"];
[tableColumn bind:@"value" toObject: mediaArrayController withKeyPath:@"arrangedObjects.stateAsImage" options:nil];
/* 6- Bind the @"contentArray" and contentMediaList of the mediaArrayController */
[mediaArrayController bind:@"contentArray" toObject:categoriesTreeController withKeyPath:@"selection.childrenInCategoriesListForDetailView.media" options:nil];
[mediaArrayController bind:@"contentMediaList" toObject:categoriesTreeController withKeyPath:@"selection.childrenInCategoriesListForDetailView.parentMediaList" options:nil];
/* 7- Aspect */
[mediaListView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList];
[mediaListView setAllowsTypeSelect:YES];
/***********************************
* videoView setup
*/
[videoView setItemsTree:controller.categories];
[videoView setNodeKeyPath:@"childrenInVideoView"];
[videoView setContentKeyPath:@"descriptionInVideoView"];
[videoView setTarget:self];
[videoView setAction:@selector(videoViewItemClicked:)];
/***********************************
* Toolbar setup
*/
/***********************************
* Other interface element setup
*/
#if 0
[mediaListItemsCount bind:@"displayPatternValue1" toObject:mediaArrayController withKeyPath:@"arrangedObjects.@count" options:[NSDictionary dictionaryWithObject:@"%{value1}@ items" forKey:NSDisplayPatternBindingOption]];
[mediaListItemFetchedStatus bind:@"animate" toObject:categoriesTreeController withKeyPath:@"selection.currentlyFetchingItems" options:[NSDictionary dictionaryWithObject:@"%{value1}@ items" forKey:NSDisplayPatternBindingOption]];
[fillScreenButton bind:@"value" toObject:videoView withKeyPath:@"fillScreen" options: nil];
[fullScreenButton bind:@"value" toObject:videoView withKeyPath:@"fullScreen" options: nil];
[fullScreenButton bind:@"enabled" toObject:mediaPlayer withKeyPath:@"media" options: [NSDictionary dictionaryWithObject:@"NonNilAsBoolTransformer" forKey:NSValueTransformerNameBindingOption]];
[fillScreenButton bind:@"enabled" toObject:mediaPlayer withKeyPath:@"media" options: [NSDictionary dictionaryWithObject:@"NonNilAsBoolTransformer" forKey:NSValueTransformerNameBindingOption]];
[mediaReadingProgressSlider bind:@"enabled" toObject:mediaPlayer withKeyPath:@"media" options: [NSDictionary dictionaryWithObject:@"NonNilAsBoolTransformer" forKey:NSValueTransformerNameBindingOption]];
[mediaReadingProgressSlider bind:@"enabled2" toObject:mediaPlayer withKeyPath:@"seekable" options: nil];
[mediaReadingProgressSlider bind:@"value" toObject:mediaPlayer withKeyPath:@"position" options:
[NSDictionary dictionaryWithObjectsAndKeys:@"Float10000FoldTransformer", NSValueTransformerNameBindingOption,
[NSNumber numberWithBool:NO], NSConditionallySetsEnabledBindingOption, nil ]];
[mediaReadingProgressText bind:@"value" toObject:mediaPlayer withKeyPath:@"time.stringValue" options: nil];
[mediaDescriptionText bind:@"value" toObject:mediaPlayer withKeyPath:@"description" options: nil];
[self bind:@"representedFilename" toObject:mediaPlayer withKeyPath:@"media.url" options: [NSDictionary dictionaryWithObject:@"URLToRepresentedFileNameTransformer" forKey:NSValueTransformerNameBindingOption]];
[self bind:@"title" toObject:mediaPlayer withKeyPath:@"description" options: nil];
[navigatorViewToggleButton bind:@"value" toObject:self withKeyPath:@"navigatorViewVisible" options: nil];
#endif
/* Playlist buttons */
#if 0
[removePlaylistButton bind:@"enabled" toObject:categoriesTreeController withKeyPath:@"selection.editableInCategoriesList" options: nil];
#endif
[removePlaylistButton setTarget:categoriesTreeController];
[removePlaylistButton setAction:@selector(remove:)];
[addPlaylistButton setTarget:controller];
[addPlaylistButton setAction:@selector(addPlaylist:)];
/* mediaPlayer */
#if 0
[mediaPlayerPlayPauseStopButton bind:@"enabled" toObject:mediaPlayer withKeyPath:@"media" options: [NSDictionary dictionaryWithObject:@"NonNilAsBoolTransformer" forKey:NSValueTransformerNameBindingOption]];
[mediaPlayerPlayPauseStopButton bind:@"state" toObject:mediaPlayer withKeyPath:@"playing" options: nil];
[mediaPlayerPlayPauseStopButton bind:@"alternateImage" toObject:mediaPlayer withKeyPath:@"stateAsButtonAlternateImage" options: nil];
[mediaPlayerPlayPauseStopButton bind:@"image" toObject:mediaPlayer withKeyPath:@"stateAsButtonImage" options: nil];
[mediaPlayerBackwardPrevButton bind:@"enabled" toObject:mediaPlayer withKeyPath:@"playing" options: nil];
[mediaPlayerForwardNextButton bind:@"enabled" toObject:mediaPlayer withKeyPath:@"playing" options: nil];
#endif
[mediaPlayerForwardNextButton setTarget:mediaPlayer];
[mediaPlayerForwardNextButton setAction:@selector(fastForward)];
[mediaPlayerBackwardPrevButton setTarget:mediaPlayer];
[mediaPlayerBackwardPrevButton setAction:@selector(rewind)];
[mediaPlayerPlayPauseStopButton setTarget:mediaPlayer];
[mediaPlayerPlayPauseStopButton setAction:@selector(pause)];
/* Last minute setup */
[categoriesListView expandItem:nil expandChildren:YES];
[categoriesListView selectRowIndexes:[NSIndexSet indexSetWithIndex:[categoriesListView numberOfRows] > 0 ? [categoriesListView numberOfRows]-1 : 0] byExtendingSelection:NO];
[self setNavigatorViewVisible:NO animate:NO];
[self showWindow:self];
[mainSplitView setDelegate:self];
}
- (BOOL)navigatorViewVisible
{
return [mainSplitView sliderPosition] <= [mainSplitView bounds].size.width - [mainSplitView dividerThickness] - 30.f /* To be tolerant */;
}
- (void)setNavigatorViewVisible:(BOOL)wantsVisible animate:(BOOL)animate
{
if( [self navigatorViewVisible] == wantsVisible )
return;
if( !animate ) [self willChangeValueForKey:@"navigatorViewVisible"];
VLCOneSplitView * splitView = animate ? [mainSplitView animator] : mainSplitView;
if( wantsVisible )
{
if( navigatorViewWidth >= [mainSplitView bounds].size.width - 200.f )
navigatorViewWidth = [mainSplitView bounds].size.width - 200.f;
[splitView setSliderPosition:navigatorViewWidth];
}
else
{
navigatorViewWidth = [videoView frame].size.width;
[splitView setSliderPosition:[mainSplitView bounds].size.width - [mainSplitView dividerThickness]];
}
if( !animate ) [self didChangeValueForKey:@"navigatorViewVisible"];
}
- (void)setNavigatorViewVisible:(BOOL)wantsVisible
{
[self setNavigatorViewVisible:wantsVisible animate:YES];
}
- (IBAction)mediaListViewItemDoubleClicked:(id)sender
{
if([[mediaArrayController selectedObjects] count] <= 0 )
return;
[mediaPlayer setMedia:[[mediaArrayController selectedObjects] objectAtIndex:0]];
[mediaPlayer play];
}
- (void)videoViewItemClicked:(id)sender
{
id object = [sender selectedObject];
NSAssert( [object isKindOfClass:[VLCMedia class]], @"Object is not a VLCMedia" );
[mediaPlayer setMedia:object];
[mediaPlayer play];
}
@end
/******************************************************************************
* @implementation VLCMainWindowController (NSToolbarDelegating)
*/
@implementation VLCMainWindowController (NSToolbarDelegating)
/* Our item identifiers */
static NSString * VLCToolbarMediaControl = @"VLCToolbarMediaControl";
static NSString * VLCToolbarMediaAudioVolume = @"VLCToolbarMediaAudioVolume";
static NSString * VLCToolbarMediaDescription = @"VLCToolbarMediaDescription";
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar *)toolbar
{
return [NSArray arrayWithObjects:
NSToolbarCustomizeToolbarItemIdentifier,
NSToolbarFlexibleSpaceItemIdentifier,
NSToolbarSpaceItemIdentifier,
NSToolbarSeparatorItemIdentifier,
VLCToolbarMediaControl,
VLCToolbarMediaAudioVolume,
VLCToolbarMediaDescription,
nil ];
}
- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar
{
return [NSArray arrayWithObjects:
VLCToolbarMediaControl,
VLCToolbarMediaAudioVolume,
VLCToolbarMediaDescription,
nil ];
}
- (NSToolbarItem *) toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag
{
NSToolbarItem *toolbarItem = [[[NSToolbarItem alloc] initWithItemIdentifier: itemIdentifier] autorelease];
if( [itemIdentifier isEqual: VLCToolbarMediaControl] )
{
[toolbarItem setLabel:@"Media Controls"];
[toolbarItem setPaletteLabel:@"Media Controls"];
[toolbarItem setView:toolbarMediaControl];
[toolbarItem setMinSize:[[toolbarItem view] frame].size];
[toolbarItem setMaxSize:[[toolbarItem view] frame].size];
/* TODO: setup a menu */
}
else if( [itemIdentifier isEqual: VLCToolbarMediaAudioVolume] )
{
[toolbarItem setLabel:@"Audio Volume"];
[toolbarItem setPaletteLabel:@"Audio Volume"];
[toolbarItem setView:toolbarMediaAudioVolume];
[toolbarItem setMinSize:[[toolbarItem view] frame].size];
[toolbarItem setMaxSize:[[toolbarItem view] frame].size];
/* TODO: setup a menu */
}
else if( [itemIdentifier isEqual: VLCToolbarMediaDescription] )
{
[toolbarItem setLabel:@"Media Description"];
[toolbarItem setPaletteLabel:@"Media Description"];
[toolbarItem setView:toolbarMediaDescription];
[toolbarItem setMinSize:[[toolbarItem view] frame].size];
[toolbarItem setMaxSize:NSMakeSize(10000 /* Can be really big */, NSHeight([[toolbarItem view] frame]))];
/* TODO: setup a menu */
}
else
{
/* itemIdentifier referred to a toolbar item that is not
* provided or supported by us or Cocoa
* Returning nil will inform the toolbar
* that this kind of item is not supported */
toolbarItem = nil;
}
return toolbarItem;
}
@end
/******************************************************************************
* VLCMainWindowController (CategoriesListDelegate)
*/
@implementation VLCMainWindowController (CategoriesListDelegate)
- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item
{
return [[item representedObject] isKindOfClass:[NSDictionary class]];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
{
return !([[item representedObject] isKindOfClass:[NSDictionary class]]);
}
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
[cell setRepresentedObject:[item representedObject]];
}
@end
/******************************************************************************
* VLCMainWindowController (CategoriesListDataSource)
*/
@implementation VLCMainWindowController (CategoriesListDataSource)
/* Drag and drop */
- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id < NSDraggingInfo >)info item:(id)item childIndex:(NSInteger)index
{
int i;
if(![item respondsToSelector:@selector(representedObject)])
return NO;
NSArray *droppedItems = [[info draggingPasteboard] propertyListForType:@"VLCMediaURLType"];
if( !droppedItems )
droppedItems = [[info draggingPasteboard] propertyListForType:NSFilenamesPboardType];
if( !droppedItems )
droppedItems = [[info draggingPasteboard] propertyListForType:NSURLPboardType];
NSAssert( droppedItems, @"Dropped an unsupported object type on the outline View" );
VLCMediaList * mediaList = [(VLCMedia *)[item representedObject] subitems];
for (i = 0; i < [droppedItems count]; i++)
{
NSString * filename = [droppedItems objectAtIndex:i];
VLCMedia *media = [VLCMedia mediaWithPath:filename];
[mediaList lock];
[mediaList insertMedia:media atIndex:index+1];
[mediaList unlock];
}
return YES;
}
- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id < NSDraggingInfo >)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
{
NSArray *droppedItems = [[info draggingPasteboard] propertyListForType:@"VLCMediaURLType"];
if( !droppedItems )
droppedItems = [[info draggingPasteboard] propertyListForType:NSFilenamesPboardType];
if( !droppedItems )
droppedItems = [[info draggingPasteboard] propertyListForType:NSURLPboardType];
if(! droppedItems ||
![item respondsToSelector:@selector(representedObject)] ||
![[item representedObject] isKindOfClass:[VLCMedia class]] )
{
return NSDragOperationNone;
}
return NSDragOperationMove;
}
@end
/******************************************************************************
* VLCMainWindowController (SplitViewDelegate)
*/
@implementation VLCMainWindowController (SplitViewDelegate)
- (void)splitViewWillResizeSubviews:(NSNotification *)aNotification
{
[self willChangeValueForKey:@"navigatorViewVisible"];
}
- (void)splitViewDidResizeSubviews:(NSNotification *)aNotification
{
[self didChangeValueForKey:@"navigatorViewVisible"];
}
@end
/*****************************************************************************
* VLCMediaArrayController.h: NSArrayController subclass specific to media
* list.
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
#import <VLCKit/VLCKit.h>
@interface VLCMediaArrayController : NSArrayController
{
VLCMediaList * contentMediaList;
}
/* Usually set through a bindings. Contents is provided by the
* super class contentArray bindings. This is useful to
* get the media list ability to be read-write. */
@property (retain) VLCMediaList * contentMediaList;
@end
/*****************************************************************************
* VLCMediaArrayController.m: NSArrayController subclass specific to media
* list.
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import "VLCMediaArrayController.h"
@implementation VLCMediaArrayController
@synthesize contentMediaList;
@end
/******************************************************************************
* VLCMediaArrayController (NSTableViewDataSource)
*/
@implementation VLCMediaArrayController (NSTableViewDataSource)
/* Dummy implementation, because that seems to be needed */
- (int)numberOfRowsInTableView:(NSTableView *)tableView
{
return 0;
}
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn
row:(int)row
{
return nil;
}
/* Implement drag and drop */
- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info
proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op
{
return [contentMediaList isReadOnly] || op == NSTableViewDropOn ? NSDragOperationNone : NSDragOperationGeneric;
}
- (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id <NSDraggingInfo>)info
row:(int)row dropOperation:(NSTableViewDropOperation)operation
{
int i;
row = 0;
NSArray *droppedItems = [[info draggingPasteboard] propertyListForType:NSFilenamesPboardType];
if( !droppedItems )
droppedItems = [[info draggingPasteboard] propertyListForType:NSURLPboardType];
NSAssert( contentMediaList, @"No contentMediaList" );
for (i = 0; i < [droppedItems count]; i++)
{
NSString * filename = [droppedItems objectAtIndex:i];
VLCMedia *media = [VLCMedia mediaWithPath:filename];
[contentMediaList lock];
[contentMediaList insertMedia:media atIndex:row];
[contentMediaList unlock];
}
return YES;
}
- (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard
{
NSMutableArray *array = [NSMutableArray arrayWithCapacity:[rowIndexes count]];
int i = [rowIndexes firstIndex];
do {
[array addObject:[[contentMediaList mediaAtIndex:i] url]];
} while ((i = [rowIndexes indexGreaterThanIndex:i]) != NSNotFound);
[pboard declareTypes:[NSArray arrayWithObject:@"VLCMediaURLType"] owner:self];
[pboard setPropertyList:array forType:@"VLCMediaURLType"];
return YES;
}
@end
//
// VLCMediaLayer.h
// VLC
//
// Created by Pierre d'Herbemont on 1/14/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#import <VLCKit/VLCKit.h>
@interface VLCMediaLayer : CALayer {
BOOL displayFullInformation;
VLCMedia * media;
CATextLayer * titleLayer;
CATextLayer * artistLayer;
CATextLayer * genreLayer;
CALayer * artworkLayer;
}
+ (id)layerWithMedia:(VLCMedia *)media;
@property (assign) BOOL displayFullInformation;
@property (retain,readonly) VLCMedia * media;
@property (retain,readonly) CATextLayer * titleLayer;
@property (retain,readonly) CATextLayer * artistLayer;
@property (retain,readonly) CATextLayer * genreLayer;
@property (retain,readonly) CALayer * artworkLayer;
@end
//
// VLCMediaLayer.m
// VLC
//
// Created by Pierre d'Herbemont on 1/14/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "VLCMediaLayer.h"
/*****************************************************************************
* Some configuration first. Defines the size of the artwork layer.
*/
static CGSize kArtworkSize = { 256., 256. };
/*****************************************************************************
* @interface VLCMediaLayer (Private)
*/
@interface VLCMediaLayer (Private)
- (void)updateSublayers;
@end
/*****************************************************************************
* @interface VLCMediaLayer ()
*/
@interface VLCMediaLayer ()
@property (retain,readwrite) VLCMedia * media;
@property (retain,readwrite) CATextLayer * titleLayer;
@property (retain,readwrite) CATextLayer * artistLayer;
@property (retain,readwrite) CATextLayer * genreLayer;
@property (retain,readwrite) CALayer * artworkLayer;
@end
/*****************************************************************************
* @implementation VLCMediaLayer
*/
@implementation VLCMediaLayer
@synthesize displayFullInformation;
@synthesize media;
@synthesize titleLayer;
@synthesize genreLayer;
@synthesize artistLayer;
@synthesize artworkLayer;
+ (id)layer
{
return [self layerWithMedia:[VLCMedia mediaAsNodeWithName:@"Empty Media"]];
}
+ (id)layerWithMedia:(VLCMedia *)aMedia
{
VLCMediaLayer * me = [super layer];
if(!me) return nil;
me.media = aMedia;
me.displayFullInformation = YES;
/* Set the default layout */
me.titleLayer = [CATextLayer layer];
me.artistLayer = [CATextLayer layer];
me.genreLayer = [CATextLayer layer];
CALayer * textLayer = [CALayer layer];
NSDictionary * textStyle = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:12], @"cornerRadius",
[NSValue valueWithSize:NSMakeSize(5, 0)], @"margin",
@"Lucida-Bold", @"font",
CGColorCreateGenericGray(0.5, 1.),@"foregroundColor",
[NSNumber numberWithInteger:18], @"fontSize",
[NSNumber numberWithFloat: .8], @"shadowOpacity",
[NSNumber numberWithFloat: 1.], @"shadowRadius",
kCAAlignmentLeft, @"alignmentMode",
nil];
NSDictionary * textTitleStyle = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger:12], @"cornerRadius",
[NSValue valueWithSize:NSMakeSize(5, 0)], @"margin",
@"Lucida", @"font",
[NSNumber numberWithInteger:26], @"fontSize",
[NSNumber numberWithFloat: .7], @"shadowOpacity",
[NSNumber numberWithFloat: 3.], @"shadowRadius",
kCAAlignmentLeft, @"alignmentMode",
nil];
/* First off, text */
me.titleLayer.style = textTitleStyle;
me.titleLayer.string = @"Title";
me.titleLayer.name = @"title";
[me.titleLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinX relativeTo:@"superlayer" attribute:kCAConstraintMinX offset:0.]];
[me.titleLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxX relativeTo:@"superlayer" attribute:kCAConstraintMaxX offset:0.]];
[me.titleLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinY relativeTo:@"artist" attribute:kCAConstraintMaxY offset:10.]];
me.artistLayer.style = textStyle;
me.artistLayer.string = @"Artist";
me.artistLayer.name = @"artist";
[me.artistLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinX relativeTo:@"title" attribute:kCAConstraintMinX]];
[me.artistLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxX relativeTo:@"title" attribute:kCAConstraintMaxX]];
[me.artistLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY relativeTo:@"superlayer" attribute:kCAConstraintMidY]];
me.genreLayer.style = textStyle;
me.genreLayer.string = @"Genre";
me.genreLayer.name = @"genre";
[me.genreLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinX relativeTo:@"title" attribute:kCAConstraintMinX]];
[me.genreLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxX relativeTo:@"title" attribute:kCAConstraintMaxX]];
[me.genreLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxY relativeTo:@"artist" attribute:kCAConstraintMinY offset:-10.]];
[textLayer addSublayer:me.titleLayer];
[textLayer addSublayer:me.artistLayer];
[textLayer addSublayer:me.genreLayer];
textLayer.contentsGravity = kCAGravityCenter;
textLayer.layoutManager = [CAConstraintLayoutManager layoutManager];
/* Empty layer for picture */
me.artworkLayer = [CALayer layer];
me.artworkLayer.backgroundColor = CGColorCreateGenericGray(0.5, 0.4);
me.artworkLayer.borderColor = CGColorCreateGenericRGB(1., 1., 1., .8);
me.artworkLayer.borderWidth = 3.0;
// me.artworkLayer.frame = CGRectMake(0.,0., kArtworkSize.width, kArtworkSize.height);
textLayer.frame = CGRectMake(0.,0., kArtworkSize.width, kArtworkSize.height);
/* Position the text and the artwork layer */
CALayer * container = [CALayer layer];
me.artworkLayer.name = @"artworkLayer";
textLayer.name = @"textLayer";
container.name = @"artContainer";
container.layoutManager = [CAConstraintLayoutManager layoutManager];
[container addSublayer:me.artworkLayer];
[container addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinX relativeTo:@"superlayer" attribute:kCAConstraintMinX offset:60.]];
[container addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY relativeTo:@"superlayer" attribute:kCAConstraintMidY]];
[container addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintHeight relativeTo:@"superlayer" attribute:kCAConstraintHeight scale:.6 offset:0.]];
[container addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxX relativeTo:@"superlayer" attribute:kCAConstraintMidX]];
[me.artworkLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinX relativeTo:@"superlayer" attribute:kCAConstraintMinX]];
[me.artworkLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinY relativeTo:@"superlayer" attribute:kCAConstraintMinY]];
[me.artworkLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxY relativeTo:@"superlayer" attribute:kCAConstraintMaxY]];
[me.artworkLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxX relativeTo:@"superlayer" attribute:kCAConstraintMaxX]];
[textLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMinX relativeTo:@"artContainer" attribute:kCAConstraintMaxX]];
[textLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMaxX relativeTo:@"superlayer" attribute:kCAConstraintMaxX ]];
[textLayer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY relativeTo:@"artContainer" attribute:kCAConstraintMidY]];
me.artworkLayer.zPosition = -30.f;
me.artworkLayer.shadowOpacity = .3;
me.artworkLayer.shadowRadius = 10.;
static CATransform3D rot, projection;
static BOOL transformInited = NO;
if( !transformInited )
{
rot = CATransform3DMakeRotation(.1
, 0., 1., 0.);
projection = CATransform3DIdentity;
projection.m34 = 1. / -80.;
transformInited = YES;
}
me.artworkLayer.transform = rot;
container.sublayerTransform = projection;
me.layoutManager = [CAConstraintLayoutManager layoutManager];
[me addSublayer:textLayer];
[me addSublayer:container];
[me updateSublayers];
/* The following will trigger -observeValueForKeyPath: ofObject: change: context: */
[me.media addObserver:me forKeyPath:@"metaDictionary.title" options:NSKeyValueObservingOptionNew context:nil];
[me.media addObserver:me forKeyPath:@"metaDictionary.genre" options:NSKeyValueObservingOptionNew context:nil];
[me.media addObserver:me forKeyPath:@"metaDictionary.artist" options:NSKeyValueObservingOptionNew context:nil];
[me.media addObserver:me forKeyPath:@"metaDictionary.artwork" options:NSKeyValueObservingOptionNew context:nil];
return me;
}
- (void)dealloc
{
/* Previously registered in +layerWithMediaArrayController: +layerWithMedia:*/
[self.media removeObserver:self forKeyPath:@"metaDictionary.title"];
[self.media removeObserver:self forKeyPath:@"metaDictionary.genre"];
[self.media removeObserver:self forKeyPath:@"metaDictionary.artist"];
[self.media removeObserver:self forKeyPath:@"metaDictionary.artwork"];
[super dealloc];
}
@end
/*****************************************************************************
* @implementation VLCMediaLayer (Private)
*/
@implementation VLCMediaLayer (Private)
- (void)updateSublayers
{
[CATransaction begin];
self.titleLayer.string = [self.media.metaDictionary objectForKey:@"title"];
NSString * artist = [self.media.metaDictionary objectForKey:@"artist"];
self.artistLayer.string = artist ? artist : @"No Artist";
NSString * genre = [self.media.metaDictionary objectForKey:@"genre"];
self.genreLayer.string = genre ? genre : @"No Genre";
if( [self.media valueForKeyPath:@"metaDictionary.artwork"] )
{
self.artworkLayer.contents = (id)[[self.media valueForKeyPath:@"metaDictionary.artwork"] CGImage];
self.artworkLayer.contentsGravity = kCAGravityResizeAspect;
self.artworkLayer.borderWidth = 0.;
self.artworkLayer.backgroundColor = nil;
}
[CATransaction commit];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if( [keyPath hasPrefix:@"metaDictionary"] )
{
[self updateSublayers];
return;
}
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
@end
//
// VLCMediaListLayer.h
// VLC
//
// Created by Pierre d'Herbemont on 1/14/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import <QuartzCore/QuartzCore.h>
#import <VLCKit/VLCKit.h>
#import "VLCMediaLayer.h"
#import "VLCMediaArrayController.h"
@interface VLCMediaListLayer : CALayer {
NSArray * content;
NSUInteger selectedIndex;
VLCMediaLayer * previousLayer;
VLCMediaLayer * selectedLayer;
VLCMediaLayer * nextLayer;
VLCMediaArrayController * controller;
}
+ (id)layer;
+ (id)layerWithMediaArrayController:(VLCMediaArrayController *)aController;
@property (retain,readwrite) NSArray * content;
@property (readwrite) NSUInteger selectedIndex;
@property (retain,readwrite) VLCMediaArrayController * controller;
@end
//
// VLCMediaListLayer.m
// VLC
//
// Created by Pierre d'Herbemont on 1/14/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "VLCMediaListLayer.h"
/*****************************************************************************
* @implementation VLCMediaListLayer
*/
@interface VLCMediaListLayer (Private)
- (VLCMediaLayer *)selectedLayer;
- (VLCMediaLayer *)previousLayer;
- (VLCMediaLayer *)nextLayer;
- (void)changeSelectedLayerToNextIndex;
- (void)changeSelectedLayerToPreviousIndex;
- (void)resetLayers;
- (void)setSelectedLayer:(VLCMediaLayer *)layer;
- (void)setPreviousLayer:(VLCMediaLayer *)layer;
- (void)setNextLayer:(VLCMediaLayer *)layer;
@end
/*****************************************************************************
* @implementation VLCMediaListLayer
*/
@implementation VLCMediaListLayer
@synthesize selectedIndex;
@synthesize content;
@synthesize controller;
+ (id)layer
{
VLCMediaListLayer * me = [super layer];
me.layoutManager = [CAConstraintLayoutManager layoutManager];
[CATransaction commit];
me->selectedIndex = NSNotFound;
return me;
}
+ (id)layerWithMediaArrayController:(VLCMediaArrayController *)aController
{
VLCMediaListLayer * me = [VLCMediaListLayer layer];
me.controller = aController;
/* The following will trigger -observeValueForKeyPath: ofObject: change: context: */
[me.controller addObserver:me forKeyPath:@"arrangedObjects" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
[me.controller addObserver:me forKeyPath:@"selectionIndex" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
[me.controller addObserver:me forKeyPath:@"contentMediaList" options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:nil];
return me;
}
- (void)dealloc
{
/* Previously registered in +layerWithMediaArrayController: */
[self.controller removeObserver:self forKeyPath:@"arrangedObjects"];
[self.controller removeObserver:self forKeyPath:@"contentMediaList"];
[self.controller removeObserver:self forKeyPath:@"selectionIndex"];
[super dealloc];
}
@end
/*****************************************************************************
* @implementation VLCMediaListLayer (Private)
*/
@implementation VLCMediaListLayer (Private)
+ (NSSet *)keyPathsForValuesAffectingSelectedLayer
{
return [NSSet setWithObjects:@"selectedLayer", @"content", nil];
}
- (VLCMediaLayer *)selectedLayer
{
VLCMedia * media = (self.selectedIndex != NSNotFound) ? [self.content objectAtIndex:self.selectedIndex ] : nil;
if( !media )
{
CATextLayer * layer = [CATextLayer layer];
CALayer * container = [CALayer layer];
container.layoutManager = [CAConstraintLayoutManager layoutManager];
if([self.controller.contentMediaList isReadOnly])
layer.string = @"Empty";
else if ([self.content count])
layer.string = @"Empty search.";
else
layer.string = @"Drag and Drop a movie or a music here.";
layer.alignmentMode = kCAAlignmentCenter;
layer.wrapped = YES;
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY relativeTo:@"superlayer" attribute:kCAConstraintMidY]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidX relativeTo:@"superlayer" attribute:kCAConstraintMidX]];
[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintWidth relativeTo:@"superlayer" attribute:kCAConstraintWidth]];
[container addSublayer:layer];
return (VLCMediaLayer *)container;
}
if( [selectedLayer isKindOfClass:[VLCMediaLayer class]] && [media compare:[selectedLayer media]] == NSOrderedSame )
return [[selectedLayer retain] autorelease];
return [VLCMediaLayer layerWithMedia:[self.content objectAtIndex:self.selectedIndex]];
}
- (VLCMediaLayer *)previousLayer
{
if( self.selectedIndex == NSNotFound )
return nil;
VLCMedia * media = self.selectedIndex > 0 ? [self.content objectAtIndex:self.selectedIndex - 1] : nil;
if( !media )
return nil;
if( [previousLayer isKindOfClass:[VLCMediaLayer class]] && [media compare:[previousLayer media]] == NSOrderedSame )
return [[previousLayer retain] autorelease];
return [VLCMediaLayer layerWithMedia: media ];
}
- (VLCMediaLayer *)nextLayer
{
if( self.selectedIndex == NSNotFound )
return nil;
VLCMedia * media = self.selectedIndex + 1 < [content count] ? [self.content objectAtIndex:self.selectedIndex + 1] : nil;
if( !media )
return nil;
if( [nextLayer isKindOfClass:[VLCMediaLayer class]] && [media compare:[nextLayer media]] == NSOrderedSame )
return [[nextLayer retain] autorelease];
return [VLCMediaLayer layerWithMedia: media ];
}
- (void)changeSelectedLayerToNextIndex
{
if(!nextLayer)
{
/* Can't do anything */
return;
}
selectedIndex++;
/* Remove offscreen layer. Without actions */
if( previousLayer )
{
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithBool:YES] forKey:kCATransactionDisableActions];
[previousLayer removeFromSuperlayer];
[CATransaction commit];
}
[CATransaction begin];
if ( [[NSApp currentEvent] modifierFlags] & NSShiftKeyMask )
[CATransaction setValue:[NSNumber numberWithFloat:1.5] forKey:kCATransactionAnimationDuration];
[self setPreviousLayer: selectedLayer];
[self setSelectedLayer: nextLayer];
[self setNextLayer: [self nextLayer]];
[CATransaction commit];
/* Move the new nextLayer layer on screen. Without Actions */
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithBool:YES] forKey:kCATransactionDisableActions];
[self addSublayer: nextLayer];
[CATransaction commit];
}
- (void)changeSelectedLayerToPreviousIndex
{
if(!previousLayer)
{
/* Can't do anything */
return;
}
selectedIndex--;
/* Remove offscreen layer. Without actions */
if( nextLayer )
{
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithBool:YES] forKey:kCATransactionDisableActions];
[nextLayer removeFromSuperlayer];
[CATransaction commit];
}
[CATransaction begin];
if ( [[NSApp currentEvent] modifierFlags] & NSShiftKeyMask )
[CATransaction setValue:[NSNumber numberWithFloat:1.5] forKey:kCATransactionAnimationDuration];
[self setNextLayer: selectedLayer];
[self setSelectedLayer: previousLayer];
[self setPreviousLayer: [self previousLayer]];
[CATransaction commit];
/* Move the new previous layer on screen. Without Actions */
[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithBool:YES] forKey:kCATransactionDisableActions];
[self addSublayer:previousLayer];
[CATransaction commit];
}
- (void)gotoIndex:(NSUInteger)index;
{
if( selectedIndex == index )
return;
if( selectedIndex > index )
{
/* It is ok to scroll five layers */
if( selectedIndex - index < 5 )
{
while( index < selectedIndex )
[self changeSelectedLayerToPreviousIndex];
return;
}
[self changeSelectedLayerToPreviousIndex];
[self changeSelectedLayerToPreviousIndex];
selectedIndex = index;
[self resetLayers];
}
else
{
if( index - selectedIndex < 5 )
{
while( index > selectedIndex )
[self changeSelectedLayerToNextIndex];
return;
}
[self changeSelectedLayerToNextIndex];
[self changeSelectedLayerToNextIndex];
selectedIndex = index;
[self resetLayers];
}
}
- (void)resetLayers
{
VLCMediaLayer * layer;
[CATransaction begin];
layer = [self previousLayer];
if( previousLayer != layer )
{
if( previousLayer ) [self replaceSublayer:previousLayer with:layer];
else [self addSublayer:layer];
[self setPreviousLayer:layer];
}
layer = [self selectedLayer];
if( selectedLayer != layer )
{
if( selectedLayer ) [self replaceSublayer:selectedLayer with:layer];
else [self addSublayer:layer];
[self setSelectedLayer:layer];
}
layer = [self nextLayer];
if( nextLayer != layer )
{
if( nextLayer ) [self replaceSublayer:nextLayer with:layer];
else [self addSublayer:layer];
[self setNextLayer:layer];
}
[CATransaction commit];
}
- (void)setSelectedLayer:(VLCMediaLayer *)layer
{
[selectedLayer autorelease];
if( !layer )
{
selectedLayer = nil;
return;
}
selectedLayer = [layer retain];
selectedLayer.frame = [self bounds];
[selectedLayer setAutoresizingMask:kCALayerWidthSizable|kCALayerHeightSizable];
}
- (void)setPreviousLayer:(VLCMediaLayer *)layer
{
[previousLayer autorelease];
if( !layer )
{
previousLayer = nil;
return;
}
previousLayer = [layer retain];
CGRect frame = [self bounds];
frame.origin.x -= frame.size.width;
previousLayer.frame = frame;
[previousLayer setAutoresizingMask:kCALayerMaxXMargin|kCALayerHeightSizable];
}
- (void)setNextLayer:(VLCMediaLayer *)layer
{
[nextLayer autorelease];
if( !layer )
{
nextLayer = nil;
return;
}
nextLayer = [layer retain];
CGRect frame = [self bounds];
frame.origin.x += frame.size.width;
nextLayer.frame = frame;
[nextLayer setAutoresizingMask:kCALayerMinXMargin|kCALayerHeightSizable];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if([keyPath isEqualToString:@"selectionIndex"])
{
if ( selectedIndex == NSNotFound || [object selectionIndex] == NSNotFound )
{
selectedIndex = [object selectionIndex];
if(selectedIndex == NSNotFound && [content count])
{
selectedIndex = 0;
}
[self resetLayers];
return;
}
[self gotoIndex: [object selectionIndex]];
return;
}
if([keyPath isEqualToString:@"arrangedObjects"] || [keyPath isEqualToString:@"contentMediaList"])
{
selectedIndex = [object selectionIndex];
if(selectedIndex == NSNotFound && [[object arrangedObjects] count])
{
selectedIndex = 0;
}
[content release];
content = [[object arrangedObjects] retain];
[self resetLayers];
return;
}
[self observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
@end
/*****************************************************************************
* VLCValueTransformer.m: NSValueTransformer subclasses
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id$
*
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#import <Cocoa/Cocoa.h>
@interface VLCFloat10000FoldTransformer : NSValueTransformer {
}
@end
@interface VLCNonNilAsBoolTransformer : NSValueTransformer {
}
@end
@interface VLCURLToRepresentedFileNameTransformer : NSValueTransformer {
}
@end
@interface VLCSelectionIndexToDescriptionTransformer : NSValueTransformer {
}
@end
//
// VLCValueTransformer.m
// VLC
//
// Created by Pierre d'Herbemont on 12/29/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "VLCValueTransformer.h"
@implementation VLCFloat10000FoldTransformer
+ (Class)transformedValueClass
{
return [NSNumber class];
}
+ (BOOL)allowsReverseTransformation
{
return YES;
}
- (id)transformedValue:(id)value
{
if( !value ) return nil;
if(![value respondsToSelector: @selector(floatValue)])
{
[NSException raise: NSInternalInconsistencyException
format: @"Value (%@) does not respond to -floatValue.",
[value class]];
return nil;
}
return [NSNumber numberWithFloat: [value floatValue]*10000.];
}
- (id)reverseTransformedValue:(id)value
{
if( !value ) return nil;
if(![value respondsToSelector: @selector(floatValue)])
{
[NSException raise: NSInternalInconsistencyException
format: @"Value (%@) does not respond to -floatValue.",
[value class]];
return nil;
}
return [NSNumber numberWithFloat: [value floatValue]/10000.];
}
@end
@implementation VLCNonNilAsBoolTransformer
+ (Class)transformedValueClass
{
return [NSObject class];
}
+ (BOOL)allowsReverseTransformation
{
return NO;
}
- (NSNumber *)transformedValue:(id)value
{
return [NSNumber numberWithBool: !!value];
}
@end
@implementation VLCURLToRepresentedFileNameTransformer
+ (Class)transformedValueClass
{
return [NSURL class];
}
+ (BOOL)allowsReverseTransformation
{
return NO;
}
- (NSString *)transformedValue:(id)value
{
if( ![value isKindOfClass:[NSURL class]] || ![value isFileURL] )
return @"";
return [value path];
}
@end
@implementation VLCSelectionIndexToDescriptionTransformer
+ (Class)transformedValueClass
{
return [NSNumber class];
}
+ (BOOL)allowsReverseTransformation
{
return NO;
}
- (NSString *)transformedValue:(id)value
{
if( ![value isKindOfClass:[NSNumber class]])
return @"";
return [value intValue] == NSNotFound ? @"" : [NSString stringWithFormat:@"%@ of ", value];
}
@end
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 44;
objects = {
/* Begin PBXAggregateTarget section */
633BD70D0D2AE0DF0012A314 /* vlc-contrib-core-framework-app */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 633BD7150D2AE1170012A314 /* Build configuration list for PBXAggregateTarget "vlc-contrib-core-framework-app" */;
buildPhases = (
);
dependencies = (
63E930B80D5F43FA006B31CD /* PBXTargetDependency */,
63E930B60D5F43E9006B31CD /* PBXTargetDependency */,
);
name = "vlc-contrib-core-framework-app";
productName = "vlc-contrib-core-framework-app";
};
637F33DF0D2AEE05001E70AB /* vlc-framework-app */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 637F33F80D2AEE67001E70AB /* Build configuration list for PBXAggregateTarget "vlc-framework-app" */;
buildPhases = (
);
dependencies = (
63E930BA0D5F4404006B31CD /* PBXTargetDependency */,
632F3C280D316FB5003BBC56 /* PBXTargetDependency */,
);
name = "vlc-framework-app";
productName = "vlc-framework-app";
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
632F3E260D326FF0003BBC56 /* pause.png in Resources */ = {isa = PBXBuildFile; fileRef = 632F3E250D326FF0003BBC56 /* pause.png */; };
633BD4BC0D2A90470012A314 /* VLCValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 633BD4AA0D2A90470012A314 /* VLCValueTransformer.m */; };
633BD4BD0D2A90470012A314 /* VLCMediaArrayController.m in Sources */ = {isa = PBXBuildFile; fileRef = 633BD4AC0D2A90470012A314 /* VLCMediaArrayController.m */; };
633BD4BE0D2A90470012A314 /* VLCMainWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 633BD4AD0D2A90470012A314 /* VLCMainWindow.m */; };
633BD4BF0D2A90470012A314 /* VLCExceptionHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 633BD4AF0D2A90470012A314 /* VLCExceptionHandler.m */; };
633BD4C00D2A90470012A314 /* VLCController.m in Sources */ = {isa = PBXBuildFile; fileRef = 633BD4B10D2A90470012A314 /* VLCController.m */; };
633BD4C10D2A90470012A314 /* VLCBrowsableVideoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 633BD4B30D2A90470012A314 /* VLCBrowsableVideoView.m */; };
633BD4C20D2A90470012A314 /* VLCAppBindings.m in Sources */ = {isa = PBXBuildFile; fileRef = 633BD4B50D2A90470012A314 /* VLCAppBindings.m */; };
633BD4C30D2A90470012A314 /* VLCAppAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 633BD4B90D2A90470012A314 /* VLCAppAdditions.m */; };
633BD4C40D2A90470012A314 /* ImageAndTextCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 633BD4BA0D2A90470012A314 /* ImageAndTextCell.m */; };
633BD4DA0D2A90C80012A314 /* dialog-error.png in Resources */ = {isa = PBXBuildFile; fileRef = 633BD4D80D2A90C80012A314 /* dialog-error.png */; };
633BD4DB0D2A90C80012A314 /* applications-internet.png in Resources */ = {isa = PBXBuildFile; fileRef = 633BD4D90D2A90C80012A314 /* applications-internet.png */; };
63541FA90D3BA1DB001F6433 /* VLCMediaLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 63541FA80D3BA1DB001F6433 /* VLCMediaLayer.m */; };
635422050D3BE019001F6433 /* VLCMainWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 635422040D3BE019001F6433 /* VLCMainWindowController.m */; };
635424930D3C1394001F6433 /* VLCMediaListLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 635424920D3C1394001F6433 /* VLCMediaListLayer.m */; };
63874B190D25960600F738AD /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63874B170D25960600F738AD /* MainWindow.xib */; };
638B823B0D35294500128F2B /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 638B823A0D35294500128F2B /* QuickTime.framework */; };
638F47110D216C8F008E4912 /* playlist.png in Resources */ = {isa = PBXBuildFile; fileRef = 638F47100D216C8F008E4912 /* playlist.png */; };
63A742B30D2759C1002D41A0 /* ExceptionHandling.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63A742B20D2759C1002D41A0 /* ExceptionHandling.framework */; };
63E380AA0D1C65A600FD6958 /* volume_high.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E380A80D1C65A600FD6958 /* volume_high.png */; };
63E380AB0D1C65A600FD6958 /* volume_low.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E380A90D1C65A600FD6958 /* volume_low.png */; };
63E380AE0D1C65D100FD6958 /* play.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E380AC0D1C65D100FD6958 /* play.png */; };
63E380AF0D1C65D100FD6958 /* play_blue.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E380AD0D1C65D100FD6958 /* play_blue.png */; };
63E380B20D1C65F200FD6958 /* skip_forward_active.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E380B00D1C65F200FD6958 /* skip_forward_active.png */; };
63E380B30D1C65F200FD6958 /* skip_forward_blue.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E380B10D1C65F200FD6958 /* skip_forward_blue.png */; };
63E380B60D1C65FC00FD6958 /* skip_previous_active.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E380B40D1C65FC00FD6958 /* skip_previous_active.png */; };
63E380B70D1C65FC00FD6958 /* skip_previous_blue.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E380B50D1C65FC00FD6958 /* skip_previous_blue.png */; };
63E380DF0D1C6FD800FD6958 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63E380DE0D1C6FD800FD6958 /* QuartzCore.framework */; };
63E768830D3503E200258089 /* VLCFullScreenControllerWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 63E768820D3503E200258089 /* VLCFullScreenControllerWindow.m */; };
63E768BF0D3507EF00258089 /* fs_volume_slider_knob.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768A40D3507EF00258089 /* fs_volume_slider_knob.png */; };
63E768C00D3507EF00258089 /* fs_background.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768A50D3507EF00258089 /* fs_background.png */; };
63E768C10D3507EF00258089 /* fs_exit_fullscreen_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768A60D3507EF00258089 /* fs_exit_fullscreen_highlight.png */; };
63E768C20D3507EF00258089 /* fs_exit_fullscreen.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768A70D3507EF00258089 /* fs_exit_fullscreen.png */; };
63E768C30D3507EF00258089 /* fs_forward_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768A80D3507EF00258089 /* fs_forward_highlight.png */; };
63E768C40D3507EF00258089 /* fs_forward.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768A90D3507EF00258089 /* fs_forward.png */; };
63E768C50D3507EF00258089 /* fs_pause_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768AA0D3507EF00258089 /* fs_pause_highlight.png */; };
63E768C60D3507EF00258089 /* fs_pause.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768AB0D3507EF00258089 /* fs_pause.png */; };
63E768C70D3507EF00258089 /* fs_play_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768AC0D3507EF00258089 /* fs_play_highlight.png */; };
63E768C80D3507EF00258089 /* fs_play.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768AD0D3507EF00258089 /* fs_play.png */; };
63E768C90D3507EF00258089 /* fs_rewind_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768AE0D3507EF00258089 /* fs_rewind_highlight.png */; };
63E768CA0D3507EF00258089 /* fs_rewind.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768AF0D3507EF00258089 /* fs_rewind.png */; };
63E768CB0D3507EF00258089 /* fs_skip_next_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768B00D3507EF00258089 /* fs_skip_next_highlight.png */; };
63E768CC0D3507EF00258089 /* fs_skip_next.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768B10D3507EF00258089 /* fs_skip_next.png */; };
63E768CD0D3507EF00258089 /* fs_skip_previous_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768B20D3507EF00258089 /* fs_skip_previous_highlight.png */; };
63E768CE0D3507EF00258089 /* fs_skip_previous.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768B30D3507EF00258089 /* fs_skip_previous.png */; };
63E768CF0D3507EF00258089 /* fs_stop_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768B40D3507EF00258089 /* fs_stop_highlight.png */; };
63E768D00D3507EF00258089 /* fs_stop.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768B50D3507EF00258089 /* fs_stop.png */; };
63E768D10D3507EF00258089 /* fs_time_slider_knob_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768B60D3507EF00258089 /* fs_time_slider_knob_highlight.png */; };
63E768D20D3507EF00258089 /* fs_time_slider_knob.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768B70D3507EF00258089 /* fs_time_slider_knob.png */; };
63E768D30D3507EF00258089 /* fs_time_slider.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768B80D3507EF00258089 /* fs_time_slider.png */; };
63E768D40D3507EF00258089 /* fs_volume_max_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768B90D3507EF00258089 /* fs_volume_max_highlight.png */; };
63E768D50D3507EF00258089 /* fs_volume_max.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768BA0D3507EF00258089 /* fs_volume_max.png */; };
63E768D60D3507EF00258089 /* fs_volume_mute_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768BB0D3507EF00258089 /* fs_volume_mute_highlight.png */; };
63E768D70D3507EF00258089 /* fs_volume_mute.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768BC0D3507EF00258089 /* fs_volume_mute.png */; };
63E768D80D3507EF00258089 /* fs_volume_slider_bar.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768BD0D3507EF00258089 /* fs_volume_slider_bar.png */; };
63E768D90D3507EF00258089 /* fs_volume_slider_knob_highlight.png in Resources */ = {isa = PBXBuildFile; fileRef = 63E768BE0D3507EF00258089 /* fs_volume_slider_knob_highlight.png */; };
63E76A530D35225700258089 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63E76A520D35225700258089 /* Carbon.framework */; };
63E930C60D5F4463006B31CD /* VLCKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63E930B20D5F430E006B31CD /* VLCKit.framework */; };
8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */ = {isa = PBXBuildFile; fileRef = 29B97318FDCFA39411CA2CEA /* MainMenu.nib */; };
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
632F3C270D316FB5003BBC56 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8D1107260486CEB800E47090;
remoteInfo = VLC;
};
63E930B10D5F430E006B31CD /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 633BD69D0D2ACE520012A314 /* VLCKit.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 8DC2EF5B0486A6940098B216;
remoteInfo = VLCKit;
};
63E930B50D5F43E9006B31CD /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = 8D1107260486CEB800E47090;
remoteInfo = VLC;
};
63E930B70D5F43FA006B31CD /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 633BD69D0D2ACE520012A314 /* VLCKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 633BD6D20D2ADE040012A314;
remoteInfo = "vlc-contrib-core-framework";
};
63E930B90D5F4404006B31CD /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 633BD69D0D2ACE520012A314 /* VLCKit.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 8DC2EF4F0486A6940098B216;
remoteInfo = VLCKit;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
29B97319FDCFA39411CA2CEA /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/MainMenu.nib; sourceTree = "<group>"; };
29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
32CA4F630368D1EE00C91783 /* VLC_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VLC_Prefix.pch; sourceTree = "<group>"; };
632F3E250D326FF0003BBC56 /* pause.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = pause.png; path = ../../../extras/package/macosx/Resources/pause.png; sourceTree = SOURCE_ROOT; };
633BD4AA0D2A90470012A314 /* VLCValueTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCValueTransformer.m; path = Sources/VLCValueTransformer.m; sourceTree = "<group>"; };
633BD4AB0D2A90470012A314 /* VLCValueTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCValueTransformer.h; path = Sources/VLCValueTransformer.h; sourceTree = "<group>"; };
633BD4AC0D2A90470012A314 /* VLCMediaArrayController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCMediaArrayController.m; path = Sources/VLCMediaArrayController.m; sourceTree = "<group>"; };
633BD4AD0D2A90470012A314 /* VLCMainWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCMainWindow.m; path = Sources/VLCMainWindow.m; sourceTree = "<group>"; };
633BD4AE0D2A90470012A314 /* VLCMediaArrayController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCMediaArrayController.h; path = Sources/VLCMediaArrayController.h; sourceTree = "<group>"; };
633BD4AF0D2A90470012A314 /* VLCExceptionHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCExceptionHandler.m; path = Sources/VLCExceptionHandler.m; sourceTree = "<group>"; };
633BD4B00D2A90470012A314 /* VLCMainWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCMainWindow.h; path = Sources/VLCMainWindow.h; sourceTree = "<group>"; };
633BD4B10D2A90470012A314 /* VLCController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCController.m; path = Sources/VLCController.m; sourceTree = "<group>"; };
633BD4B20D2A90470012A314 /* VLCExceptionHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCExceptionHandler.h; path = Sources/VLCExceptionHandler.h; sourceTree = "<group>"; };
633BD4B30D2A90470012A314 /* VLCBrowsableVideoView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCBrowsableVideoView.m; path = Sources/VLCBrowsableVideoView.m; sourceTree = "<group>"; };
633BD4B40D2A90470012A314 /* VLCController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCController.h; path = Sources/VLCController.h; sourceTree = "<group>"; };
633BD4B50D2A90470012A314 /* VLCAppBindings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCAppBindings.m; path = Sources/VLCAppBindings.m; sourceTree = "<group>"; };
633BD4B60D2A90470012A314 /* VLCBrowsableVideoView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCBrowsableVideoView.h; path = Sources/VLCBrowsableVideoView.h; sourceTree = "<group>"; };
633BD4B70D2A90470012A314 /* VLCAppBindings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCAppBindings.h; path = Sources/VLCAppBindings.h; sourceTree = "<group>"; };
633BD4B80D2A90470012A314 /* VLCAppAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCAppAdditions.h; path = Sources/VLCAppAdditions.h; sourceTree = "<group>"; };
633BD4B90D2A90470012A314 /* VLCAppAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCAppAdditions.m; path = Sources/VLCAppAdditions.m; sourceTree = "<group>"; };
633BD4BA0D2A90470012A314 /* ImageAndTextCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ImageAndTextCell.m; path = Sources/ImageAndTextCell.m; sourceTree = "<group>"; };
633BD4BB0D2A90470012A314 /* ImageAndTextCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ImageAndTextCell.h; path = Sources/ImageAndTextCell.h; sourceTree = "<group>"; };
633BD4D80D2A90C80012A314 /* dialog-error.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "dialog-error.png"; path = "Icons/dialog-error.png"; sourceTree = "<group>"; };
633BD4D90D2A90C80012A314 /* applications-internet.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "applications-internet.png"; path = "Icons/applications-internet.png"; sourceTree = "<group>"; };
633BD69D0D2ACE520012A314 /* VLCKit.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = VLCKit.xcodeproj; path = ../framework/VLCKit.xcodeproj; sourceTree = SOURCE_ROOT; };
63541FA70D3BA1DB001F6433 /* VLCMediaLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCMediaLayer.h; path = Sources/VLCMediaLayer.h; sourceTree = "<group>"; };
63541FA80D3BA1DB001F6433 /* VLCMediaLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCMediaLayer.m; path = Sources/VLCMediaLayer.m; sourceTree = "<group>"; };
635422030D3BE019001F6433 /* VLCMainWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCMainWindowController.h; path = Sources/VLCMainWindowController.h; sourceTree = "<group>"; };
635422040D3BE019001F6433 /* VLCMainWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCMainWindowController.m; path = Sources/VLCMainWindowController.m; sourceTree = "<group>"; };
635424910D3C1394001F6433 /* VLCMediaListLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCMediaListLayer.h; path = Sources/VLCMediaListLayer.h; sourceTree = "<group>"; };
635424920D3C1394001F6433 /* VLCMediaListLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCMediaListLayer.m; path = Sources/VLCMediaListLayer.m; sourceTree = "<group>"; };
63874B180D25960600F738AD /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainWindow.xib; sourceTree = "<group>"; };
638B823A0D35294500128F2B /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = "<absolute>"; };
638F47100D216C8F008E4912 /* playlist.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = playlist.png; path = ../../../modules/gui/qt4/pixmaps/playlist/playlist.png; sourceTree = SOURCE_ROOT; };
63A742B20D2759C1002D41A0 /* ExceptionHandling.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ExceptionHandling.framework; path = /System/Library/Frameworks/ExceptionHandling.framework; sourceTree = "<absolute>"; };
63E380A80D1C65A600FD6958 /* volume_high.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = volume_high.png; path = ../../../extras/package/macosx/Resources/volume_high.png; sourceTree = SOURCE_ROOT; };
63E380A90D1C65A600FD6958 /* volume_low.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = volume_low.png; path = ../../../extras/package/macosx/Resources/volume_low.png; sourceTree = SOURCE_ROOT; };
63E380AC0D1C65D100FD6958 /* play.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = play.png; path = ../../../extras/package/macosx/Resources/play.png; sourceTree = SOURCE_ROOT; };
63E380AD0D1C65D100FD6958 /* play_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = play_blue.png; path = ../../../extras/package/macosx/Resources/play_blue.png; sourceTree = SOURCE_ROOT; };
63E380B00D1C65F200FD6958 /* skip_forward_active.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = skip_forward_active.png; path = ../../../extras/package/macosx/Resources/skip_forward_active.png; sourceTree = SOURCE_ROOT; };
63E380B10D1C65F200FD6958 /* skip_forward_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = skip_forward_blue.png; path = ../../../extras/package/macosx/Resources/skip_forward_blue.png; sourceTree = SOURCE_ROOT; };
63E380B40D1C65FC00FD6958 /* skip_previous_active.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = skip_previous_active.png; path = ../../../extras/package/macosx/Resources/skip_previous_active.png; sourceTree = SOURCE_ROOT; };
63E380B50D1C65FC00FD6958 /* skip_previous_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = skip_previous_blue.png; path = ../../../extras/package/macosx/Resources/skip_previous_blue.png; sourceTree = SOURCE_ROOT; };
63E380DE0D1C6FD800FD6958 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = /System/Library/Frameworks/QuartzCore.framework; sourceTree = "<absolute>"; };
63E768810D3503E200258089 /* VLCFullScreenControllerWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCFullScreenControllerWindow.h; path = Sources/VLCFullScreenControllerWindow.h; sourceTree = "<group>"; };
63E768820D3503E200258089 /* VLCFullScreenControllerWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCFullScreenControllerWindow.m; path = Sources/VLCFullScreenControllerWindow.m; sourceTree = "<group>"; };
63E768A40D3507EF00258089 /* fs_volume_slider_knob.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_volume_slider_knob.png; path = ../../../extras/package/macosx/Resources/fs_volume_slider_knob.png; sourceTree = SOURCE_ROOT; };
63E768A50D3507EF00258089 /* fs_background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_background.png; path = ../../../extras/package/macosx/Resources/fs_background.png; sourceTree = SOURCE_ROOT; };
63E768A60D3507EF00258089 /* fs_exit_fullscreen_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_exit_fullscreen_highlight.png; path = ../../../extras/package/macosx/Resources/fs_exit_fullscreen_highlight.png; sourceTree = SOURCE_ROOT; };
63E768A70D3507EF00258089 /* fs_exit_fullscreen.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_exit_fullscreen.png; path = ../../../extras/package/macosx/Resources/fs_exit_fullscreen.png; sourceTree = SOURCE_ROOT; };
63E768A80D3507EF00258089 /* fs_forward_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_forward_highlight.png; path = ../../../extras/package/macosx/Resources/fs_forward_highlight.png; sourceTree = SOURCE_ROOT; };
63E768A90D3507EF00258089 /* fs_forward.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_forward.png; path = ../../../extras/package/macosx/Resources/fs_forward.png; sourceTree = SOURCE_ROOT; };
63E768AA0D3507EF00258089 /* fs_pause_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_pause_highlight.png; path = ../../../extras/package/macosx/Resources/fs_pause_highlight.png; sourceTree = SOURCE_ROOT; };
63E768AB0D3507EF00258089 /* fs_pause.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_pause.png; path = ../../../extras/package/macosx/Resources/fs_pause.png; sourceTree = SOURCE_ROOT; };
63E768AC0D3507EF00258089 /* fs_play_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_play_highlight.png; path = ../../../extras/package/macosx/Resources/fs_play_highlight.png; sourceTree = SOURCE_ROOT; };
63E768AD0D3507EF00258089 /* fs_play.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_play.png; path = ../../../extras/package/macosx/Resources/fs_play.png; sourceTree = SOURCE_ROOT; };
63E768AE0D3507EF00258089 /* fs_rewind_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_rewind_highlight.png; path = ../../../extras/package/macosx/Resources/fs_rewind_highlight.png; sourceTree = SOURCE_ROOT; };
63E768AF0D3507EF00258089 /* fs_rewind.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_rewind.png; path = ../../../extras/package/macosx/Resources/fs_rewind.png; sourceTree = SOURCE_ROOT; };
63E768B00D3507EF00258089 /* fs_skip_next_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_skip_next_highlight.png; path = ../../../extras/package/macosx/Resources/fs_skip_next_highlight.png; sourceTree = SOURCE_ROOT; };
63E768B10D3507EF00258089 /* fs_skip_next.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_skip_next.png; path = ../../../extras/package/macosx/Resources/fs_skip_next.png; sourceTree = SOURCE_ROOT; };
63E768B20D3507EF00258089 /* fs_skip_previous_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_skip_previous_highlight.png; path = ../../../extras/package/macosx/Resources/fs_skip_previous_highlight.png; sourceTree = SOURCE_ROOT; };
63E768B30D3507EF00258089 /* fs_skip_previous.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_skip_previous.png; path = ../../../extras/package/macosx/Resources/fs_skip_previous.png; sourceTree = SOURCE_ROOT; };
63E768B40D3507EF00258089 /* fs_stop_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_stop_highlight.png; path = ../../../extras/package/macosx/Resources/fs_stop_highlight.png; sourceTree = SOURCE_ROOT; };
63E768B50D3507EF00258089 /* fs_stop.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_stop.png; path = ../../../extras/package/macosx/Resources/fs_stop.png; sourceTree = SOURCE_ROOT; };
63E768B60D3507EF00258089 /* fs_time_slider_knob_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_time_slider_knob_highlight.png; path = ../../../extras/package/macosx/Resources/fs_time_slider_knob_highlight.png; sourceTree = SOURCE_ROOT; };
63E768B70D3507EF00258089 /* fs_time_slider_knob.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_time_slider_knob.png; path = ../../../extras/package/macosx/Resources/fs_time_slider_knob.png; sourceTree = SOURCE_ROOT; };
63E768B80D3507EF00258089 /* fs_time_slider.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_time_slider.png; path = ../../../extras/package/macosx/Resources/fs_time_slider.png; sourceTree = SOURCE_ROOT; };
63E768B90D3507EF00258089 /* fs_volume_max_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_volume_max_highlight.png; path = ../../../extras/package/macosx/Resources/fs_volume_max_highlight.png; sourceTree = SOURCE_ROOT; };
63E768BA0D3507EF00258089 /* fs_volume_max.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_volume_max.png; path = ../../../extras/package/macosx/Resources/fs_volume_max.png; sourceTree = SOURCE_ROOT; };
63E768BB0D3507EF00258089 /* fs_volume_mute_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_volume_mute_highlight.png; path = ../../../extras/package/macosx/Resources/fs_volume_mute_highlight.png; sourceTree = SOURCE_ROOT; };
63E768BC0D3507EF00258089 /* fs_volume_mute.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_volume_mute.png; path = ../../../extras/package/macosx/Resources/fs_volume_mute.png; sourceTree = SOURCE_ROOT; };
63E768BD0D3507EF00258089 /* fs_volume_slider_bar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_volume_slider_bar.png; path = ../../../extras/package/macosx/Resources/fs_volume_slider_bar.png; sourceTree = SOURCE_ROOT; };
63E768BE0D3507EF00258089 /* fs_volume_slider_knob_highlight.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = fs_volume_slider_knob_highlight.png; path = ../../../extras/package/macosx/Resources/fs_volume_slider_knob_highlight.png; sourceTree = SOURCE_ROOT; };
63E76A520D35225700258089 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
8D1107320486CEB800E47090 /* VLC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VLC.app; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8D11072E0486CEB800E47090 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
63E930C60D5F4463006B31CD /* VLCKit.framework in Frameworks */,
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
63E380DF0D1C6FD800FD6958 /* QuartzCore.framework in Frameworks */,
63A742B30D2759C1002D41A0 /* ExceptionHandling.framework in Frameworks */,
63E76A530D35225700258089 /* Carbon.framework in Frameworks */,
638B823B0D35294500128F2B /* QuickTime.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
638B823A0D35294500128F2B /* QuickTime.framework */,
63A742B20D2759C1002D41A0 /* ExceptionHandling.framework */,
63E380DE0D1C6FD800FD6958 /* QuartzCore.framework */,
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
);
name = "Linked Frameworks";
sourceTree = "<group>";
};
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
29B97324FDCFA39411CA2CEA /* AppKit.framework */,
13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
29B97325FDCFA39411CA2CEA /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8D1107320486CEB800E47090 /* VLC.app */,
);
name = Products;
sourceTree = "<group>";
};
29B97314FDCFA39411CA2CEA /* VLC */ = {
isa = PBXGroup;
children = (
63E76A520D35225700258089 /* Carbon.framework */,
633BD6A40D2ACE5E0012A314 /* Dependencies */,
63874AF40D2591CE00F738AD /* Sources */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
);
name = VLC;
sourceTree = "<group>";
};
29B97315FDCFA39411CA2CEA /* Other Sources */ = {
isa = PBXGroup;
children = (
32CA4F630368D1EE00C91783 /* VLC_Prefix.pch */,
29B97316FDCFA39411CA2CEA /* main.m */,
);
name = "Other Sources";
sourceTree = "<group>";
};
29B97317FDCFA39411CA2CEA /* Resources */ = {
isa = PBXGroup;
children = (
63C551960C7F6AD100B202D3 /* Images */,
8D1107310486CEB800E47090 /* Info.plist */,
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
63874B170D25960600F738AD /* MainWindow.xib */,
29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
);
name = Resources;
sourceTree = "<group>";
};
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
);
name = Frameworks;
sourceTree = "<group>";
};
633BD4620D2A8DF30012A314 /* Internals */ = {
isa = PBXGroup;
children = (
633BD4B20D2A90470012A314 /* VLCExceptionHandler.h */,
633BD4AF0D2A90470012A314 /* VLCExceptionHandler.m */,
);
name = Internals;
sourceTree = "<group>";
};
633BD6A40D2ACE5E0012A314 /* Dependencies */ = {
isa = PBXGroup;
children = (
633BD69D0D2ACE520012A314 /* VLCKit.xcodeproj */,
);
name = Dependencies;
sourceTree = "<group>";
};
63874AF40D2591CE00F738AD /* Sources */ = {
isa = PBXGroup;
children = (
633BD4B40D2A90470012A314 /* VLCController.h */,
633BD4B10D2A90470012A314 /* VLCController.m */,
63874AF60D25920800F738AD /* Additions */,
633BD4620D2A8DF30012A314 /* Internals */,
63874AF50D2591EF00F738AD /* Video */,
63874AF70D25922800F738AD /* Media List Management */,
63874B0E0D25928400F738AD /* Window Management */,
);
name = Sources;
sourceTree = "<group>";
};
63874AF50D2591EF00F738AD /* Video */ = {
isa = PBXGroup;
children = (
633BD4B60D2A90470012A314 /* VLCBrowsableVideoView.h */,
633BD4B30D2A90470012A314 /* VLCBrowsableVideoView.m */,
63E768810D3503E200258089 /* VLCFullScreenControllerWindow.h */,
63E768820D3503E200258089 /* VLCFullScreenControllerWindow.m */,
63541FA70D3BA1DB001F6433 /* VLCMediaLayer.h */,
63541FA80D3BA1DB001F6433 /* VLCMediaLayer.m */,
635424910D3C1394001F6433 /* VLCMediaListLayer.h */,
635424920D3C1394001F6433 /* VLCMediaListLayer.m */,
);
name = Video;
sourceTree = "<group>";
};
63874AF60D25920800F738AD /* Additions */ = {
isa = PBXGroup;
children = (
633BD4AB0D2A90470012A314 /* VLCValueTransformer.h */,
633BD4AA0D2A90470012A314 /* VLCValueTransformer.m */,
633BD4B70D2A90470012A314 /* VLCAppBindings.h */,
633BD4B50D2A90470012A314 /* VLCAppBindings.m */,
633BD4B80D2A90470012A314 /* VLCAppAdditions.h */,
633BD4B90D2A90470012A314 /* VLCAppAdditions.m */,
633BD4BB0D2A90470012A314 /* ImageAndTextCell.h */,
633BD4BA0D2A90470012A314 /* ImageAndTextCell.m */,
);
name = Additions;
sourceTree = "<group>";
};
63874AF70D25922800F738AD /* Media List Management */ = {
isa = PBXGroup;
children = (
633BD4AE0D2A90470012A314 /* VLCMediaArrayController.h */,
633BD4AC0D2A90470012A314 /* VLCMediaArrayController.m */,
);
name = "Media List Management";
sourceTree = "<group>";
};
63874B0E0D25928400F738AD /* Window Management */ = {
isa = PBXGroup;
children = (
633BD4B00D2A90470012A314 /* VLCMainWindow.h */,
633BD4AD0D2A90470012A314 /* VLCMainWindow.m */,
635422030D3BE019001F6433 /* VLCMainWindowController.h */,
635422040D3BE019001F6433 /* VLCMainWindowController.m */,
);
name = "Window Management";
sourceTree = "<group>";
};
63C551960C7F6AD100B202D3 /* Images */ = {
isa = PBXGroup;
children = (
63E768860D35072F00258089 /* Categories Icons */,
63E768850D35072600258089 /* Toolbar Items */,
63E768DA0D3507F500258089 /* FullScreenControllerWindow */,
);
name = Images;
sourceTree = "<group>";
};
63E768850D35072600258089 /* Toolbar Items */ = {
isa = PBXGroup;
children = (
63E380A80D1C65A600FD6958 /* volume_high.png */,
63E380A90D1C65A600FD6958 /* volume_low.png */,
63E380AC0D1C65D100FD6958 /* play.png */,
63E380AD0D1C65D100FD6958 /* play_blue.png */,
632F3E250D326FF0003BBC56 /* pause.png */,
63E380B00D1C65F200FD6958 /* skip_forward_active.png */,
63E380B10D1C65F200FD6958 /* skip_forward_blue.png */,
63E380B40D1C65FC00FD6958 /* skip_previous_active.png */,
63E380B50D1C65FC00FD6958 /* skip_previous_blue.png */,
);
name = "Toolbar Items";
sourceTree = "<group>";
};
63E768860D35072F00258089 /* Categories Icons */ = {
isa = PBXGroup;
children = (
638F47100D216C8F008E4912 /* playlist.png */,
633BD4D80D2A90C80012A314 /* dialog-error.png */,
633BD4D90D2A90C80012A314 /* applications-internet.png */,
);
name = "Categories Icons";
sourceTree = "<group>";
};
63E768DA0D3507F500258089 /* FullScreenControllerWindow */ = {
isa = PBXGroup;
children = (
63E768A40D3507EF00258089 /* fs_volume_slider_knob.png */,
63E768A50D3507EF00258089 /* fs_background.png */,
63E768A60D3507EF00258089 /* fs_exit_fullscreen_highlight.png */,
63E768A70D3507EF00258089 /* fs_exit_fullscreen.png */,
63E768A80D3507EF00258089 /* fs_forward_highlight.png */,
63E768A90D3507EF00258089 /* fs_forward.png */,
63E768AA0D3507EF00258089 /* fs_pause_highlight.png */,
63E768AB0D3507EF00258089 /* fs_pause.png */,
63E768AC0D3507EF00258089 /* fs_play_highlight.png */,
63E768AD0D3507EF00258089 /* fs_play.png */,
63E768AE0D3507EF00258089 /* fs_rewind_highlight.png */,
63E768AF0D3507EF00258089 /* fs_rewind.png */,
63E768B00D3507EF00258089 /* fs_skip_next_highlight.png */,
63E768B10D3507EF00258089 /* fs_skip_next.png */,
63E768B20D3507EF00258089 /* fs_skip_previous_highlight.png */,
63E768B30D3507EF00258089 /* fs_skip_previous.png */,
63E768B40D3507EF00258089 /* fs_stop_highlight.png */,
63E768B50D3507EF00258089 /* fs_stop.png */,
63E768B60D3507EF00258089 /* fs_time_slider_knob_highlight.png */,
63E768B70D3507EF00258089 /* fs_time_slider_knob.png */,
63E768B80D3507EF00258089 /* fs_time_slider.png */,
63E768B90D3507EF00258089 /* fs_volume_max_highlight.png */,
63E768BA0D3507EF00258089 /* fs_volume_max.png */,
63E768BB0D3507EF00258089 /* fs_volume_mute_highlight.png */,
63E768BC0D3507EF00258089 /* fs_volume_mute.png */,
63E768BD0D3507EF00258089 /* fs_volume_slider_bar.png */,
63E768BE0D3507EF00258089 /* fs_volume_slider_knob_highlight.png */,
);
name = FullScreenControllerWindow;
sourceTree = "<group>";
};
63E930AA0D5F430E006B31CD /* Products */ = {
isa = PBXGroup;
children = (
63E930B20D5F430E006B31CD /* VLCKit.framework */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8D1107260486CEB800E47090 /* VLC */ = {
isa = PBXNativeTarget;
buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "VLC" */;
buildPhases = (
63FFDC300D2AE9D30092FC96 /* ShellScript */,
8D1107290486CEB800E47090 /* Resources */,
8D11072C0486CEB800E47090 /* Sources */,
8D11072E0486CEB800E47090 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = VLC;
productInstallPath = "$(HOME)/Applications";
productName = VLC;
productReference = 8D1107320486CEB800E47090 /* VLC.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
29B97313FDCFA39411CA2CEA /* Project object */ = {
isa = PBXProject;
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "VLC" */;
compatibilityVersion = "Xcode 3.0";
hasScannedForEncodings = 1;
mainGroup = 29B97314FDCFA39411CA2CEA /* VLC */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = 63E930AA0D5F430E006B31CD /* Products */;
ProjectRef = 633BD69D0D2ACE520012A314 /* VLCKit.xcodeproj */;
},
);
projectRoot = "";
targets = (
633BD70D0D2AE0DF0012A314 /* vlc-contrib-core-framework-app */,
637F33DF0D2AEE05001E70AB /* vlc-framework-app */,
8D1107260486CEB800E47090 /* VLC */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
63E930B20D5F430E006B31CD /* VLCKit.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = VLCKit.framework;
remoteRef = 63E930B10D5F430E006B31CD /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
8D1107290486CEB800E47090 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8D11072A0486CEB800E47090 /* MainMenu.nib in Resources */,
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
63E380AA0D1C65A600FD6958 /* volume_high.png in Resources */,
63E380AB0D1C65A600FD6958 /* volume_low.png in Resources */,
63E380AE0D1C65D100FD6958 /* play.png in Resources */,
63E380AF0D1C65D100FD6958 /* play_blue.png in Resources */,
63E380B20D1C65F200FD6958 /* skip_forward_active.png in Resources */,
63E380B30D1C65F200FD6958 /* skip_forward_blue.png in Resources */,
63E380B60D1C65FC00FD6958 /* skip_previous_active.png in Resources */,
63E380B70D1C65FC00FD6958 /* skip_previous_blue.png in Resources */,
638F47110D216C8F008E4912 /* playlist.png in Resources */,
63874B190D25960600F738AD /* MainWindow.xib in Resources */,
633BD4DA0D2A90C80012A314 /* dialog-error.png in Resources */,
633BD4DB0D2A90C80012A314 /* applications-internet.png in Resources */,
632F3E260D326FF0003BBC56 /* pause.png in Resources */,
63E768BF0D3507EF00258089 /* fs_volume_slider_knob.png in Resources */,
63E768C00D3507EF00258089 /* fs_background.png in Resources */,
63E768C10D3507EF00258089 /* fs_exit_fullscreen_highlight.png in Resources */,
63E768C20D3507EF00258089 /* fs_exit_fullscreen.png in Resources */,
63E768C30D3507EF00258089 /* fs_forward_highlight.png in Resources */,
63E768C40D3507EF00258089 /* fs_forward.png in Resources */,
63E768C50D3507EF00258089 /* fs_pause_highlight.png in Resources */,
63E768C60D3507EF00258089 /* fs_pause.png in Resources */,
63E768C70D3507EF00258089 /* fs_play_highlight.png in Resources */,
63E768C80D3507EF00258089 /* fs_play.png in Resources */,
63E768C90D3507EF00258089 /* fs_rewind_highlight.png in Resources */,
63E768CA0D3507EF00258089 /* fs_rewind.png in Resources */,
63E768CB0D3507EF00258089 /* fs_skip_next_highlight.png in Resources */,
63E768CC0D3507EF00258089 /* fs_skip_next.png in Resources */,
63E768CD0D3507EF00258089 /* fs_skip_previous_highlight.png in Resources */,
63E768CE0D3507EF00258089 /* fs_skip_previous.png in Resources */,
63E768CF0D3507EF00258089 /* fs_stop_highlight.png in Resources */,
63E768D00D3507EF00258089 /* fs_stop.png in Resources */,
63E768D10D3507EF00258089 /* fs_time_slider_knob_highlight.png in Resources */,
63E768D20D3507EF00258089 /* fs_time_slider_knob.png in Resources */,
63E768D30D3507EF00258089 /* fs_time_slider.png in Resources */,
63E768D40D3507EF00258089 /* fs_volume_max_highlight.png in Resources */,
63E768D50D3507EF00258089 /* fs_volume_max.png in Resources */,
63E768D60D3507EF00258089 /* fs_volume_mute_highlight.png in Resources */,
63E768D70D3507EF00258089 /* fs_volume_mute.png in Resources */,
63E768D80D3507EF00258089 /* fs_volume_slider_bar.png in Resources */,
63E768D90D3507EF00258089 /* fs_volume_slider_knob_highlight.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
63FFDC300D2AE9D30092FC96 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
$SRCROOT/../Framework/build/$BUILD_VARIANTS/VLCKit.framework,
);
outputPaths = (
$BUILT_PRODUCTS_DIR/$FRAMEWORKS_FOLDER_PATH/VLCKit.framework,
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if test \"$SYMROOT\" == \"$PROJECT_DIR/build\"\nthen\n\tVLCFRAMEWORK=\"$SRCROOT/../Framework/build/$CONFIGURATION/VLCKit.framework\"\nelse\n\tVLCFRAMEWORK=\"$SYMROOT/$CONFIGURATION/VLCKit.framework\"\nfi\n/Developer/Library/PrivateFrameworks/DevToolsCore.framework/Resources/pbxcp -exclude .DS_Store -exclude CVS -exclude .svn -resolve-src-symlinks $VLCFRAMEWORK $BUILT_PRODUCTS_DIR/$FRAMEWORKS_FOLDER_PATH\n\n\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8D11072C0486CEB800E47090 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8D11072D0486CEB800E47090 /* main.m in Sources */,
633BD4BC0D2A90470012A314 /* VLCValueTransformer.m in Sources */,
633BD4BD0D2A90470012A314 /* VLCMediaArrayController.m in Sources */,
633BD4BE0D2A90470012A314 /* VLCMainWindow.m in Sources */,
633BD4BF0D2A90470012A314 /* VLCExceptionHandler.m in Sources */,
633BD4C00D2A90470012A314 /* VLCController.m in Sources */,
633BD4C10D2A90470012A314 /* VLCBrowsableVideoView.m in Sources */,
633BD4C20D2A90470012A314 /* VLCAppBindings.m in Sources */,
633BD4C30D2A90470012A314 /* VLCAppAdditions.m in Sources */,
633BD4C40D2A90470012A314 /* ImageAndTextCell.m in Sources */,
63E768830D3503E200258089 /* VLCFullScreenControllerWindow.m in Sources */,
63541FA90D3BA1DB001F6433 /* VLCMediaLayer.m in Sources */,
635422050D3BE019001F6433 /* VLCMainWindowController.m in Sources */,
635424930D3C1394001F6433 /* VLCMediaListLayer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
632F3C280D316FB5003BBC56 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8D1107260486CEB800E47090 /* VLC */;
targetProxy = 632F3C270D316FB5003BBC56 /* PBXContainerItemProxy */;
};
63E930B60D5F43E9006B31CD /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 8D1107260486CEB800E47090 /* VLC */;
targetProxy = 63E930B50D5F43E9006B31CD /* PBXContainerItemProxy */;
};
63E930B80D5F43FA006B31CD /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = "vlc-contrib-core-framework";
targetProxy = 63E930B70D5F43FA006B31CD /* PBXContainerItemProxy */;
};
63E930BA0D5F4404006B31CD /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = VLCKit;
targetProxy = 63E930B90D5F4404006B31CD /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C165DFE840E0CC02AAC07 /* English */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = {
isa = PBXVariantGroup;
children = (
29B97319FDCFA39411CA2CEA /* English */,
);
name = MainMenu.nib;
sourceTree = "<group>";
};
63874B170D25960600F738AD /* MainWindow.xib */ = {
isa = PBXVariantGroup;
children = (
63874B180D25960600F738AD /* English */,
);
name = MainWindow.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
633BD70E0D2AE0DF0012A314 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
PRODUCT_NAME = "vlc-contrib-core-framework-app";
};
name = Debug;
};
633BD70F0D2AE0DF0012A314 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_ENABLE_FIX_AND_CONTINUE = NO;
PRODUCT_NAME = "vlc-contrib-core-framework-app";
ZERO_LINK = NO;
};
name = Release;
};
637F33E00D2AEE05001E70AB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
PRODUCT_NAME = "vlc-framework-app";
};
name = Debug;
};
637F33E10D2AEE05001E70AB /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_ENABLE_FIX_AND_CONTINUE = NO;
PRODUCT_NAME = "vlc-framework-app";
ZERO_LINK = NO;
};
name = Release;
};
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
"\"$(SRCROOT)/../Framework/build/Debug\"",
);
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_ENABLE_OBJC_GC = unsupported;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(HOME)/Applications";
PRODUCT_NAME = VLC;
WRAPPER_EXTENSION = app;
ZERO_LINK = YES;
};
name = Debug;
};
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH)";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_2)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1)",
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
"\"$(SRCROOT)/../Framework/build/Debug\"",
);
GCC_ENABLE_OBJC_GC = unsupported;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_MODEL_TUNING = G5;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(HOME)/Applications";
PRODUCT_NAME = VLC;
WRAPPER_EXTENSION = app;
};
name = Release;
};
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_32_BIT)";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
};
name = Debug;
};
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_32_BIT)";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
633BD7150D2AE1170012A314 /* Build configuration list for PBXAggregateTarget "vlc-contrib-core-framework-app" */ = {
isa = XCConfigurationList;
buildConfigurations = (
633BD70E0D2AE0DF0012A314 /* Debug */,
633BD70F0D2AE0DF0012A314 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
637F33F80D2AEE67001E70AB /* Build configuration list for PBXAggregateTarget "vlc-framework-app" */ = {
isa = XCConfigurationList;
buildConfigurations = (
637F33E00D2AEE05001E70AB /* Debug */,
637F33E10D2AEE05001E70AB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "VLC" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4B08A954540054247B /* Debug */,
C01FCF4C08A954540054247B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
C01FCF4E08A954540054247B /* Build configuration list for PBXProject "VLC" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C01FCF4F08A954540054247B /* Debug */,
C01FCF5008A954540054247B /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
/* End XCConfigurationList section */
};
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
}
//
// Prefix header for all source files of the 'VLC' target in the 'VLC' project
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif
//
// main.m
// VLC
//
// Created by Pierre d'Herbemont on 11/08/07.
// Copyright __MyCompanyName__ 2007. All rights reserved.
//
#import <Cocoa/Cocoa.h>
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **) argv);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment