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

MacOSX/VLC_app: Initial import. Big playlist still causes memory and cpu high...

MacOSX/VLC_app: Initial import. Big playlist still causes memory and cpu high load. Interface is ugly. Miss many functionality. But code is light. Supports multiple player. Fullscreen a-la frontrow interface (yet a bit ugly).
parent 7ea9b1c2
......@@ -5,14 +5,13 @@
<key>IBClasses</key>
<array>
<dict>
<key>CLASS</key>
<string>VLCCategoryOutlineView</string>
<key>LANGUAGE</key>
<string>ObjC</string>
<key>SUPERCLASS</key>
<string>NSOutlineView</string>
</dict>
<dict>
<key>ACTIONS</key>
<dict>
<key>detailListItemDoubleClicked</key>
<string>id</string>
<key>newMainWindow</key>
<string>id</string>
</dict>
<key>CLASS</key>
<string>VLCController</string>
<key>LANGUAGE</key>
......@@ -21,12 +20,18 @@
<dict>
<key>categoryList</key>
<string>id</string>
<key>detailItemFetchedStatus</key>
<string>id</string>
<key>detailItemsCount</key>
<string>id</string>
<key>detailList</key>
<string>id</string>
<key>detailSearchField</key>
<string>id</string>
<key>videoView</key>
<key>fillScreenButton</key>
<string>id</string>
<key>videoView</key>
<string>VLCBrowsableVideoView</string>
</dict>
<key>SUPERCLASS</key>
<string>NSObject</string>
......@@ -39,6 +44,28 @@
<key>SUPERCLASS</key>
<string>NSObject</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>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>
......
......@@ -10,7 +10,7 @@
<integer>5</integer>
<key>IBOpenObjects</key>
<array>
<integer>253</integer>
<integer>81</integer>
</array>
<key>IBSystem Version</key>
<string>9B18</string>
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!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>
......@@ -9,7 +9,7 @@
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.VLC</string>
<string>org.videolan.vlc</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
......
/*****************************************************************************
* 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>
*
* 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 NSIndexPath (VLCAppAddition)
- (NSIndexPath *)indexPathByRemovingFirstIndex;
- (NSUInteger)lastIndex;
@end
@interface NSArray (VLCAppAddition)
- (id)objectAtIndexPath:(NSIndexPath *)path withNodeKeyPath:(NSString *)nodeKeyPath;
@end
@interface NSView (VLCAppAdditions)
- (void)moveSubviewsToVisible;
@end
/* Split view that supports slider animation */
@interface VLCOneSplitView : NSSplitView
- (float)sliderPosition;
- (void)setSliderPosition:(float)newPosition;
@end
\ No newline at end of file
/*****************************************************************************
* 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>
*
* 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
- (float)sliderPosition
{
return [[[self subviews] objectAtIndex:0] frame].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
/*****************************************************************************
* 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 <VLC/VLC.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 (MasterViewBindings)
*/
@implementation VLCMediaDiscoverer (MasterViewBindings)
+(void)initialize
{
[VLCMediaDiscoverer setKeys:[NSArray arrayWithObject:@"running"] triggerChangeNotificationsForDependentKey:@"currentlyFetchingItems"];
}
+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
/* Thanks to Julien Robert, we'll have some nice auto triggered KVO event from here */
static NSDictionary * dict = nil;
if( !dict )
{
dict = [[NSDictionary dictionaryWithObjectsAndKeys:
[NSSet setWithObject:@"discoveredMedia.flatAspect"], @"childrenInMasterViewForDetailView",
nil] retain];
}
return [dict objectForKey: key];
}
/* General shortcuts */
- (BOOL)currentlyFetchingItems
{
return [self isRunning];
}
- (NSImage *)image
{
static NSImage * sdImage = nil;
if( !sdImage )
sdImage = [[NSImage imageNamed:@"applications-internet.png"] retain];
return sdImage;
}
/* MasterView specific bindings */
- (NSArray *)childrenInMasterView
{
return nil;
}
- (NSString *)descriptionInMasterView
{
return [self localizedName];
}
- (VLCMediaListAspect *)childrenInMasterViewForDetailView
{
return [[self discoveredMedia] flatAspect];
}
- (BOOL)editableInMasterView
{
return NO;
}
- (BOOL)selectableInMasterView
{
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 *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
/* Thanks to Julien Robert, we'll have some nice auto triggered KVO event from here */
static NSDictionary * dict = nil;
if( !dict )
{
dict = [[NSDictionary dictionaryWithObjectsAndKeys:
[NSSet setWithObject:@"subitems.hierarchicalNodeAspect.media"], @"childrenInMasterView",
[NSSet setWithObject:@"metaDictionary.title"], @"descriptionInMasterView",
[NSSet setWithObject:@"subitems.flatAspect"], @"childrenInMasterViewForDetailView",
[NSSet setWithObject:@"metaDictionary.title"], @"descriptionInVideoView",
[NSSet setWithObject:@"state"], @"stateAsImage",
nil] retain];
}
return [dict objectForKey: key];
}
/* MasterView specific bindings */
- (NSArray *)childrenInMasterView
{
return [[[self subitems] hierarchicalNodeAspect] valueForKeyPath:@"media"];
}
- (void)setDescriptionInMasterView:(NSString *)description
{
NSLog(@"unimplemented: meta edition");
}
- (NSString *)descriptionInMasterView
{
return [[self metaDictionary] objectForKey:@"title"];
}
- (VLCMediaListAspect *)childrenInMasterViewForDetailView
{
return [[self subitems] flatAspect];
}
- (BOOL)editableInMasterView
{
return YES;
}
- (BOOL)selectableInMasterView
{
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"];
}
/* DetailList 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)
+ (void)initialize
{
[self setKeys:[NSArray arrayWithObjects:@"playing", @"media", nil] triggerChangeNotificationsForDependentKey:@"description"];
}
- (NSString *)description
{
if([self media])
return [self valueForKeyPath:@"media.metaDictionary.title"];
else
return @"VLC Media Player";
}
@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 <VLC/VLC.h>
@interface VLCBrowsableVideoView : VLCVideoView {
BOOL menuDisplayed;
NSArray * itemsTree;
NSRange displayedItems;
NSInteger selectedIndex;
CALayer * selectionLayer;
CALayer * backLayer;
CALayer * menuLayer;
NSIndexPath * selectedPath;
NSString * nodeKeyPath;
NSString * contentKeyPath;
id selectedObject;
/* Actions on non-node items*/
id target;
SEL action;
}
/* 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;
/* 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;
@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 "VLCBrowsableVideoView.h"
#import "VLCAppAdditions.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
/******************************************************************************
* VLCBrowsableVideoView
*/
@implementation VLCBrowsableVideoView
/* Property */
@synthesize nodeKeyPath;
@synthesize contentKeyPath;
@synthesize selectedObject;
@synthesize target;
@synthesize action;
- (NSArray *)itemsTree {
return itemsTree;
}
- (void)setItemsTree:(NSArray *)newItemsTree
{
[itemsTree release];
itemsTree = [newItemsTree retain];
[self changeSelectedPath:[[[NSIndexPath alloc] init] autorelease] withSelectedIndex:0];
}
/* 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];
/* Observe our bindings */
//[self displayMenu];
//[self changeSelectedIndex:0];
}
/* 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;
}
- (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];
}
/* Event handling */
- (BOOL)acceptsFirstResponder
{
return YES;
}
-(void)moveUp:(id)sender
{
[self changeSelectedIndex:selectedIndex-1];
}
-(void)moveDown:(id)sender
{
[self changeSelectedIndex:selectedIndex+1];
}
- (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)
{
[self displayMenu];
}
else
[super keyDown: theEvent];
}
@end
/******************************************************************************
* 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( i < 0 ) i = 0;
if( i >= [items count] ) i = [items count] - 1;
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
\ No newline at end of file
/*****************************************************************************
* VLCController.h: VLC.app main controller
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id: VLCController.h 21565 2007-08-29 21:10:20Z pdherbemont $
*
* 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 <VLC/VLC.h>
#import "VLCMediaArrayController.h"
#import "VLCBrowsableVideoView.h"
@class VLCMainWindow;
#define VLCPanic( ex ) __VLCPanic( ex, __FUNCTION__, __FILE__, __LINE__ )
static inline void __VLCPanic( const char * str, const char * function, const char * file, int line_number )
{
NSRunCriticalAlertPanel( @"Error", [NSString stringWithFormat:@"The following error was encountered: %s (%s:%d %s)", str, file, line_number, function], @"Quit", nil, nil );
exit( -1 );
}
@interface VLCController : NSObject
{
NSMutableArray * arrayOfPlaylists;
NSArray * arrayOfMasters;
NSArray * arrayOfVideoViewMasters;
}
@property (readonly, retain) NSArray * arrayOfMasters;
@property (readonly, retain) NSArray * arrayOfVideoViewMasters;
- (void)newMainWindow:(id)sender;
@end
/*****************************************************************************
* VLCController.m: VLC.app main controller
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id: VLCController.m 23286 2007-11-23 21:40:20Z pdherbemont $
*
* 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 <VLC/VLC.h>
#import "VLCController.h"
#import "VLCAppAdditions.h"
#import "VLCValueTransformer.h"
@interface VLCController ()
@property (readwrite,retain) NSArray * arrayOfMasters;
@property (readwrite,retain) NSArray * arrayOfVideoViewMasters;
@end
/******************************************************************************
* VLCBrowsableVideoView
*/
@implementation VLCController
@synthesize arrayOfMasters;
@synthesize arrayOfVideoViewMasters;
- (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"];
/***********************************
* arrayOfMasters: MasterView OutlineView content
*/
NSArray * arrayOfMediaDiscoverer = [NSArray arrayWithObjects:
[[[VLCMediaDiscoverer alloc] initWithName:@"shoutcasttv"] autorelease],
[[[VLCMediaDiscoverer alloc] initWithName:@"shoutcast"] autorelease],
[[[VLCMediaDiscoverer alloc] initWithName:@"sap"] autorelease],
[[[VLCMediaDiscoverer alloc] initWithName:@"freebox"] autorelease], nil];
arrayOfPlaylists = [NSMutableArray arrayWithObjects:[VLCMedia mediaAsNodeWithName:@"Default Playlist"], nil];
NSDictionary * playlists = [NSMutableDictionary dictionaryWithObjectsAndKeys:
[@"Playlists" uppercaseString], @"descriptionInMasterView",
[@"Playlists" uppercaseString], @"descriptionInVideoView",
[NSNumber numberWithBool:NO], @"selectableInMasterView",
arrayOfPlaylists, @"childrenInMasterView",
arrayOfPlaylists, @"childrenInVideoView",
nil];
self.arrayOfMasters = [NSArray arrayWithObjects:
[NSMutableDictionary dictionaryWithObjectsAndKeys:
[@"Service Discovery" uppercaseString], @"descriptionInMasterView",
[NSNumber numberWithBool:NO], @"selectableInMasterView",
arrayOfMediaDiscoverer, @"childrenInMasterView",
nil],
playlists,
nil];
/***********************************
* videoView setup
*/
self.arrayOfVideoViewMasters = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObjectsAndKeys:
@"Service Discovery", @"descriptionInVideoView",
arrayOfMediaDiscoverer, @"childrenInVideoView",
nil],
playlists,
nil];
/* Execution will continue in applicationDidFinishLaunching */
[NSApp setDelegate:self];
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
[self newMainWindow: 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
{
[[arrayOfMasters mutableArrayValueForKey:@"[0].childrenInMasterView"] addObject:[VLCMedia mediaAsNodeWithName:@"Untitled Playlist"]];
}
@end
@implementation VLCController (ExceptionHandlerDelegating)
@end
/*****************************************************************************
* VLCExceptionHandler.h: VLCExceptionHandler implementation
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id: VLCController.h 21565 2007-08-29 21:10:20Z pdherbemont $
*
* 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: VLCController.h 21565 2007-08-29 21:10:20Z pdherbemont $
*
* 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)initialize
{
[[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];
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
/*****************************************************************************
* VLCMainWindow.h: VLCMainWindow implementation
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id: VLCController.h 21565 2007-08-29 21:10:20Z pdherbemont $
*
* 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"
@interface VLCMainWindow : NSWindow {
/* IB elements */
IBOutlet id detailItemFetchedStatus;
IBOutlet id detailItemsCount;
IBOutlet id detailSearchField;
IBOutlet NSOutlineView * categoryList;
IBOutlet NSTableView * detailList;
IBOutlet VLCBrowsableVideoView * videoView;
IBOutlet id fillScreenButton;
IBOutlet id fullScreenButton;
IBOutlet NSSlider * mediaReadingProgressSlider;
IBOutlet NSTextField * mediaReadingProgressText;
IBOutlet NSTextField * mediaDescriptionText;
IBOutlet id navigatorViewToggleButton;
IBOutlet NSSplitView * mainSplitView;
IBOutlet NSView * navigatorView;
IBOutlet NSView * videoPlayerAndControlView;
IBOutlet NSView * controlView;
IBOutlet NSButton * addPlaylistButton;
IBOutlet NSButton * removePlaylistButton;
VLCMediaPlayer * mediaPlayer;
IBOutlet VLCController * controller; /* This is a VLCController binded to the File's Owner of the nib */
/* Controllers */
NSTreeController * treeController;
VLCMediaArrayController * mediaArrayController;
/* Window state */
CGFloat navigatorHeight;
}
@property BOOL navigatorViewVisible;
@end
/*****************************************************************************
* VLCMainWindow.m: VLCMainWindow implementation
*****************************************************************************
* Copyright (C) 2007 Pierre d'Herbemont
* Copyright (C) 2007 the VideoLAN team
* $Id: VLCController.h 21565 2007-08-29 21:10:20Z pdherbemont $
*
* 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"
#import "ImageAndTextCell.h"
#import "VLCMediaArrayController.h"
#import "VLCBrowsableVideoView.h"
#import "VLCAppAdditions.h"
/******************************************************************************
* VLCMainWindow (MasterViewDataSource)
*/
@implementation VLCMainWindow (MasterViewDataSource)
- (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
/******************************************************************************
* VLCMainWindow
*/
@implementation VLCMainWindow
- (void)awakeFromNib;
{
NSTableColumn * tableColumn;
/* This one will be removable, so we keep a reference of it so we can safely call removeFromSuperview */
[navigatorView retain];
/* Check ib outlets */
NSAssert( mainSplitView, @"No split view or wrong split view");
NSAssert( fullScreenButton, @"No fullscreen button");
/***********************************
* Init the media player
*/
mediaPlayer = [[VLCMediaPlayer alloc] initWithVideoView:videoView];
/***********************************
* MasterView OutlineView content
*/
/* treeController */
treeController = [[NSTreeController alloc] init];
[treeController setContent:controller.arrayOfMasters];
[treeController setChildrenKeyPath:@"childrenInMasterView"];
//[treeController bind:@"contentArray" toObject:controller withKeyPath:@"arrayOfMasters" options:nil];
/* Bind the "name" table column */
tableColumn = [categoryList tableColumnWithIdentifier:@"name"];
[tableColumn bind:@"value" toObject: treeController withKeyPath:@"arrangedObjects.descriptionInMasterView" options:nil];
[tableColumn setEditable:YES];
/* FIXME: this doesn't work obviously. */
[tableColumn bind:@"editable" toObject: treeController withKeyPath:@"arrangedObjects.editableInMasterView" 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 */
[categoryList setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList];
[categoryList setDelegate:self];
/***********************************
* detailList setup
*/
mediaArrayController = [[VLCMediaArrayController alloc] init];
/* 1- Drag and drop */
[detailList registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSURLPboardType, nil]];
[detailList setDataSource:mediaArrayController];
/* 2- Double click */
[detailList setTarget:self];
[detailList setDoubleAction:@selector(detailListItemDoubleClicked:)];
/* 3- binding for "title" column */
tableColumn = [detailList tableColumnWithIdentifier:@"title"];
[tableColumn bind:@"value" toObject: mediaArrayController withKeyPath:@"arrangedObjects.metaDictionary.title" options:nil];
/* 4- binding for "state" column */
tableColumn = [detailList tableColumnWithIdentifier:@"state"];
[tableColumn bind:@"value" toObject: mediaArrayController withKeyPath:@"arrangedObjects.stateAsImage" options:nil];
/* 5- Search & Predicate */
NSMutableDictionary * bindingOptions = [NSMutableDictionary dictionary];
[bindingOptions setObject:@"metaDictionary.title contains[c] $value" forKey:NSPredicateFormatBindingOption];
[bindingOptions setObject:@"No Title" forKey:NSDisplayNameBindingOption];
[detailSearchField bind:@"predicate" toObject: mediaArrayController withKeyPath:@"filterPredicate" options:bindingOptions];
/* 6- Bind the @"contentArray" and contentMediaList of the mediaArrayController */
[mediaArrayController bind:@"contentArray" toObject:treeController withKeyPath:@"selection.childrenInMasterViewForDetailView.media" options:nil];
[mediaArrayController bind:@"contentMediaList" toObject:treeController withKeyPath:@"selection.childrenInMasterViewForDetailView.parentMediaList" options:nil];
/* 7- Aspect */
[detailList setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList];
[detailList setAllowsTypeSelect:YES];
/***********************************
* videoView setup
*/
[videoView setItemsTree:controller.arrayOfVideoViewMasters];
[videoView setNodeKeyPath:@"childrenInVideoView"];
[videoView setContentKeyPath:@"descriptionInVideoView"];
[videoView setTarget:self];
[videoView setAction:@selector(videoViewItemClicked:)];
/***********************************
* Other interface element setup
*/
[detailItemsCount bind:@"displayPatternValue1" toObject:mediaArrayController withKeyPath:@"arrangedObjects.@count" options:[NSDictionary dictionaryWithObject:@"%{value1}@ items" forKey:NSDisplayPatternBindingOption]];
[detailItemFetchedStatus bind:@"animate" toObject:treeController withKeyPath:@"selection.currentlyFetchingItems" options:[NSDictionary dictionaryWithObject:@"%{value1}@ items" forKey:NSDisplayPatternBindingOption]];
[fillScreenButton bind:@"value" toObject:videoView withKeyPath:@"fillScreen" options: [NSDictionary dictionaryWithObject:NSNegateBooleanTransformerName forKey:NSValueTransformerNameBindingOption]];
[fullScreenButton bind:@"value" toObject:videoView withKeyPath:@"fullScreen" options: nil];
[fullScreenButton bind:@"enabled" toObject:mediaPlayer withKeyPath:@"playing" options: nil];
[fillScreenButton bind:@"enabled" toObject:mediaPlayer withKeyPath:@"playing" options: nil];
[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];
[navigatorViewToggleButton bind:@"value" toObject:self withKeyPath:@"navigatorViewVisible" options: nil];
/* Playlist buttons */
[removePlaylistButton bind:@"enabled" toObject:treeController withKeyPath:@"selection.editableInMasterView" options: nil];
[removePlaylistButton setTarget:treeController];
[removePlaylistButton setAction:@selector(remove:)];
[addPlaylistButton setTarget:controller];
[addPlaylistButton setAction:@selector(addPlaylist:)];
[mainSplitView setDelegate:self];
/* Last minute setup */
[categoryList expandItem:nil expandChildren:YES];
[categoryList selectRowIndexes:[NSIndexSet indexSetWithIndex:[categoryList numberOfRows] > 0 ? [categoryList numberOfRows]-1 : 0] byExtendingSelection:NO];
}
- (void)dealloc
{
[navigatorView release];
[mediaPlayer release];
[treeController release];
[mediaArrayController release];
[super dealloc];
}
- (void)detailListItemDoubleClicked:(id)sender
{
[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];
}
- (BOOL)videoViewVisible
{
NSAssert( mainSplitView && [[mainSplitView subviews] count] == 2, @"No split view or wrong split view");
return ([[[mainSplitView subviews] objectAtIndex:0] frame].size.height > 50.);
}
- (BOOL)navigatorViewVisible
{
NSAssert( mainSplitView && [[mainSplitView subviews] count] == 2, @"No split view or wrong split view");
return ([[[mainSplitView subviews] objectAtIndex:1] frame].size.height > 6.);
}
- (void)setNavigatorViewVisible:(BOOL)visible
{
NSAssert( mainSplitView && [[mainSplitView subviews] count] == 2, @"No split view or wrong split view");
if(!([self navigatorViewVisible] ^ visible))
return; /* Nothing to do */
if(visible)
{
if( !navigatorHeight ) navigatorHeight = 100.f;
if( ![self videoViewVisible] && ![self navigatorViewVisible] )
{
NSRect frame = [self frame];
frame.origin.y -= navigatorHeight;
frame.size.height += navigatorHeight;
[[self animator] setFrame:frame display:YES];
}
else
[[mainSplitView animator] setSliderPosition:([mainSplitView bounds].size.height - navigatorHeight - [mainSplitView dividerThickness])];
/* Hack, because sliding cause some glitches */
[navigatorView moveSubviewsToVisible];
}
else
{
navigatorHeight = [navigatorView bounds].size.height;
NSRect frame0 = [self frame];
NSRect frame1 = [[[mainSplitView subviews] objectAtIndex: 1] frame];
frame0.size.height -= frame1.size.height;
frame0.origin.y += frame1.size.height;
frame1.size.height = 0;
[[mainSplitView animator] setSliderPosition:([mainSplitView bounds].size.height)];
/* Hack, because sliding cause some glitches */
[navigatorView moveSubviewsToVisible];
}
}
@end
@implementation VLCMainWindow (SplitViewDelegating)
- (CGFloat)splitView:(NSSplitView *)sender constrainSplitPosition:(CGFloat)proposedPosition ofSubviewAt:(NSInteger)offset
{
CGFloat minHeight = 34.;
/* Hack, because sliding cause some glitches */
[navigatorView moveSubviewsToVisible];
/* Get the bottom of the navigator view to get stuck at some points */
if( [sender bounds].size.height - proposedPosition < minHeight*3./2. &&
[sender bounds].size.height - proposedPosition >= minHeight/2 )
return [sender bounds].size.height - minHeight;
if( [sender bounds].size.height - proposedPosition < minHeight/2 )
return [sender bounds].size.height;
return proposedPosition;
}
- (void)splitView:(NSSplitView *)sender resizeSubviewsWithOldSize:(NSSize)oldSize
{
[sender adjustSubviews];
/* Hack, because sliding cause some glitches */
[navigatorView setFrame:[[navigatorView superview] bounds]];
[navigatorView moveSubviewsToVisible];
}
- (void)splitViewWillResizeSubviews:(NSNotification *)aNotification
{
/* Hack, because sliding cause some glitches */
[navigatorView moveSubviewsToVisible];
/* This could be changed from now on, so post a KVO notification */
[self willChangeValueForKey:@"navigatorViewVisible"];
}
- (void)splitViewDidResizeSubviews:(NSNotification *)aNotification
{
[self didChangeValueForKey:@"navigatorViewVisible"];
}
@end
@implementation VLCMainWindow (NSWindowDelegating)
- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize
{
if( proposedFrameSize.height < 120.f)
proposedFrameSize.height = [self minSize].height;
return proposedFrameSize;
}
@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 <VLC/VLC.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] ? 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];
for (i = 0; i < [droppedItems count]; i++)
{
NSString * filename = [droppedItems objectAtIndex:i];
VLCMedia *media = [VLCMedia mediaWithPath:filename];
[contentMediaList lock];
[contentMediaList insertMedia:media atIndex:[contentMediaList count] > 0 ? [contentMediaList count]-1 : 0];
[contentMediaList unlock];
}
return YES;
}
@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
//
// 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
......@@ -9,7 +9,29 @@
/* Begin PBXBuildFile section */
6310515A0CF7604600ACDE1E /* VLC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 631051590CF7604600ACDE1E /* VLC.framework */; };
6310515D0CF7604900ACDE1E /* VLC.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 631051590CF7604600ACDE1E /* VLC.framework */; };
63C5518D0C7F663500B202D3 /* VLCController.m in Sources */ = {isa = PBXBuildFile; fileRef = 63C5518B0C7F663500B202D3 /* VLCController.m */; };
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 */; };
63874B190D25960600F738AD /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 63874B170D25960600F738AD /* MainWindow.xib */; };
638F47110D216C8F008E4912 /* type_playlist.png in Resources */ = {isa = PBXBuildFile; fileRef = 638F47100D216C8F008E4912 /* type_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 */; };
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 = (); }; };
......@@ -39,8 +61,38 @@
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>"; };
631051590CF7604600ACDE1E /* VLC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = VLC.framework; path = ../Framework/build/Debug/VLC.framework; sourceTree = SOURCE_ROOT; };
63C5518A0C7F663500B202D3 /* VLCController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = VLCController.h; sourceTree = "<group>"; };
63C5518B0C7F663500B202D3 /* VLCController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = VLCController.m; sourceTree = "<group>"; };
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>"; };
63874B180D25960600F738AD /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainWindow.xib; sourceTree = "<group>"; };
638F47100D216C8F008E4912 /* type_playlist.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = type_playlist.png; path = ../../../modules/gui/qt4/pixmaps/type_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 = ../Resources/volume_high.png; sourceTree = SOURCE_ROOT; };
63E380A90D1C65A600FD6958 /* volume_low.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = volume_low.png; path = ../Resources/volume_low.png; sourceTree = SOURCE_ROOT; };
63E380AC0D1C65D100FD6958 /* play.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = play.png; path = ../Resources/play.png; sourceTree = SOURCE_ROOT; };
63E380AD0D1C65D100FD6958 /* play_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = play_blue.png; path = ../Resources/play_blue.png; sourceTree = SOURCE_ROOT; };
63E380B00D1C65F200FD6958 /* skip_forward_active.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = skip_forward_active.png; path = ../Resources/skip_forward_active.png; sourceTree = SOURCE_ROOT; };
63E380B10D1C65F200FD6958 /* skip_forward_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = skip_forward_blue.png; path = ../Resources/skip_forward_blue.png; sourceTree = SOURCE_ROOT; };
63E380B40D1C65FC00FD6958 /* skip_previous_active.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = skip_previous_active.png; path = ../Resources/skip_previous_active.png; sourceTree = SOURCE_ROOT; };
63E380B50D1C65FC00FD6958 /* skip_previous_blue.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = skip_previous_blue.png; path = ../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>"; };
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 */
......@@ -52,24 +104,19 @@
files = (
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
6310515A0CF7604600ACDE1E /* VLC.framework in Frameworks */,
63E380DF0D1C6FD800FD6958 /* QuartzCore.framework in Frameworks */,
63A742B30D2759C1002D41A0 /* ExceptionHandling.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
080E96DDFE201D6D7F000001 /* Classes */ = {
isa = PBXGroup;
children = (
63C5518A0C7F663500B202D3 /* VLCController.h */,
63C5518B0C7F663500B202D3 /* VLCController.m */,
);
name = Classes;
sourceTree = "<group>";
};
1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
63A742B20D2759C1002D41A0 /* ExceptionHandling.framework */,
63E380DE0D1C6FD800FD6958 /* QuartzCore.framework */,
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
631051590CF7604600ACDE1E /* VLC.framework */,
);
......@@ -97,7 +144,7 @@
29B97314FDCFA39411CA2CEA /* VLC */ = {
isa = PBXGroup;
children = (
080E96DDFE201D6D7F000001 /* Classes */,
63874AF40D2591CE00F738AD /* Sources */,
29B97315FDCFA39411CA2CEA /* Other Sources */,
29B97317FDCFA39411CA2CEA /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
......@@ -121,6 +168,7 @@
63C551960C7F6AD100B202D3 /* Images */,
8D1107310486CEB800E47090 /* Info.plist */,
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
63874B170D25960600F738AD /* MainWindow.xib */,
29B97318FDCFA39411CA2CEA /* MainMenu.nib */,
);
name = Resources;
......@@ -135,9 +183,85 @@
name = Frameworks;
sourceTree = "<group>";
};
633BD4620D2A8DF30012A314 /* Internals */ = {
isa = PBXGroup;
children = (
633BD4B20D2A90470012A314 /* VLCExceptionHandler.h */,
633BD4AF0D2A90470012A314 /* VLCExceptionHandler.m */,
);
name = Internals;
sourceTree = "<group>";
};
63874AF40D2591CE00F738AD /* Sources */ = {
isa = PBXGroup;
children = (
633BD4B10D2A90470012A314 /* VLCController.m */,
633BD4B40D2A90470012A314 /* VLCController.h */,
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 */,
);
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 */,
);
name = "Window Management";
sourceTree = "<group>";
};
63C551960C7F6AD100B202D3 /* Images */ = {
isa = PBXGroup;
children = (
638F47100D216C8F008E4912 /* type_playlist.png */,
633BD4D80D2A90C80012A314 /* dialog-error.png */,
633BD4D90D2A90C80012A314 /* applications-internet.png */,
63E380A80D1C65A600FD6958 /* volume_high.png */,
63E380A90D1C65A600FD6958 /* volume_low.png */,
63E380AC0D1C65D100FD6958 /* play.png */,
63E380AD0D1C65D100FD6958 /* play_blue.png */,
63E380B00D1C65F200FD6958 /* skip_forward_active.png */,
63E380B10D1C65F200FD6958 /* skip_forward_blue.png */,
63E380B40D1C65FC00FD6958 /* skip_previous_active.png */,
63E380B50D1C65FC00FD6958 /* skip_previous_blue.png */,
);
name = Images;
sourceTree = "<group>";
......@@ -188,6 +312,18 @@
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 /* type_playlist.png in Resources */,
63874B190D25960600F738AD /* MainWindow.xib in Resources */,
633BD4DA0D2A90C80012A314 /* dialog-error.png in Resources */,
633BD4DB0D2A90C80012A314 /* applications-internet.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -199,7 +335,15 @@
buildActionMask = 2147483647;
files = (
8D11072D0486CEB800E47090 /* main.m in Sources */,
63C5518D0C7F663500B202D3 /* VLCController.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 */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......@@ -222,6 +366,14 @@
name = MainMenu.nib;
sourceTree = "<group>";
};
63874B170D25960600F738AD /* MainWindow.xib */ = {
isa = PBXVariantGroup;
children = (
63874B180D25960600F738AD /* English */,
);
name = MainWindow.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
......@@ -237,12 +389,9 @@
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
"\"$(SRCROOT)/../Framework/build/Debug\"",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../..\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../Framework\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\\\"$(SRCROOT)/../Framework/build/Release\\\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../Framework/build/Release\"";
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;
......@@ -265,10 +414,7 @@
"$(FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2)",
"\"$(SRCROOT)/../Framework/build/Debug\"",
);
FRAMEWORK_SEARCH_PATHS_QUOTED_1 = "\"$(SRCROOT)/../..\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_2 = "\"$(SRCROOT)/../Framework\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_1 = "\\\"$(SRCROOT)/../Framework/build/Release\\\"";
FRAMEWORK_SEARCH_PATHS_QUOTED_FOR_TARGET_2 = "\"$(SRCROOT)/../Framework/build/Release\"";
GCC_ENABLE_OBJC_GC = unsupported;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_MODEL_TUNING = G5;
INFOPLIST_FILE = Info.plist;
......
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