Nibs will be added later on. No user-visible change as of yet.
Changes between 1.0.0-rc1 and 1.1.0-git:
----------------------------------------
+Mac OS X Interface:
+ * Completely reworked user interface (based upon works from GSoC 2008)
+
Changes between 0.9.9a and 1.0.0-rc1:
------------------------------------
Dylan Aïssi <aissi dot dylan at free dot fr> - French translation
Dylan Yudaken <dyudaken -- gmail # com> - hotkeys patch
Emmanuel Blindauer <manu at agat.net> - aRts audio output
+Eric Dudiak <dudiak at gmail dot com> - Mac OS X Interface rework (GSoC 2008)
Enrico Gueli <e_gueli at yahoo.it> - Brightness threshold in adjust video filter
Enrique Osuna <enrique.osuna at gmail.com> - Various bug fixes in libvlc. Major Mac OS X Framework improvements.
Eren Türkay <turkay dot eren \a/ gmail point com> - Speex boundary checks and security fix
IBOutlet id o_btn_shuffle;
IBOutlet id o_btn_addNode;
IBOutlet id o_btn_repeat;
+ IBOutlet id o_btn_repeat_embed;
+ IBOutlet id o_btn_shuffle_embed;
NSImage * o_repeat_single;
NSImage * o_repeat_all;
@end
+/*****************************************************************************
+ * VLCAutoGeneratedMenuContent interface
+ *****************************************************************************
+ * This holds our data for autogenerated menus
+ *****************************************************************************/
+@interface VLCAutoGeneratedMenuContent : NSObject
+{
+ char *psz_name;
+ vlc_object_t * _vlc_object;
+ vlc_value_t value;
+ int i_type;
+}
+
+- (id)initWithVariableName: (const char *)name
+ ofObject: (vlc_object_t *)object
+ andValue: (vlc_value_t)value
+ ofType: (int)type;
+- (const char *)name;
+- (vlc_value_t)value;
+- (vlc_object_t *)vlcObject;
+- (int)type;
+
+@end
+
/*****************************************************************************
* VLCTimeField interface
*****************************************************************************
#include <vlc_osd.h>
#include <vlc_keys.h>
-/*****************************************************************************
- * VLCAutoGeneratedMenuContent interface
- *****************************************************************************
- * This holds our data for autogenerated menus
- *****************************************************************************/
-@interface VLCAutoGeneratedMenuContent : NSObject
-{
- char *psz_name;
- vlc_object_t * _vlc_object;
- vlc_value_t value;
- int i_type;
-}
-
-- (id)initWithVariableName: (const char *)name
- ofObject: (vlc_object_t *)object
- andValue: (vlc_value_t)value
- ofType: (int)type;
-- (const char *)name;
-- (vlc_value_t)value;
-- (vlc_object_t *)vlcObject;
-- (int)type;
-
-@end
-
#pragma mark -
/*****************************************************************************
* VLCControls implementation
- (id)voutView
{
- id window;
- id voutView = nil;
- id embeddedViewList = [[VLCMain sharedInstance] embeddedList];
- NSEnumerator *enumerator = [[NSApp orderedWindows] objectEnumerator];
- while( !voutView && ( window = [enumerator nextObject] ) )
+ id o_window;
+ id o_voutView = nil;
+ id o_embeddedViewList = [[VLCMain sharedInstance] embeddedList];
+ NSEnumerator *o_enumerator = [[NSApp orderedWindows] objectEnumerator];
+ while( !o_voutView && ( o_window = [o_enumerator nextObject] ) )
{
/* We have an embedded vout */
- if( [embeddedViewList windowContainsEmbedded: window] )
+ if( [o_embeddedViewList windowContainsEmbedded: o_window] )
{
- voutView = [embeddedViewList viewForWindow: window];
+ o_voutView = [o_embeddedViewList viewForWindow: o_window];
}
/* We have a detached vout */
- else if( [[window className] isEqualToString: @"VLCVoutWindow"] )
+ else if( [[o_window className] isEqualToString: @"VLCVoutWindow"] )
{
- voutView = [window voutView];
+ o_voutView = [o_window voutView];
}
}
- return [[voutView retain] autorelease];
+ return [[o_voutView retain] autorelease];
}
- (IBAction)stop:(id)sender
{
[o_btn_repeat setImage: o_repeat_single];
[o_btn_repeat setAlternateImage: o_repeat_all];
+ [o_btn_repeat_embed setImage: [NSImage imageNamed:@"sidebarRepeatOneOn"]];
}
- (void)repeatAll
{
[o_btn_repeat setImage: o_repeat_all];
[o_btn_repeat setAlternateImage: o_repeat_off];
+ [o_btn_repeat_embed setImage: [NSImage imageNamed:@"sidebarRepeatOn"]];
}
- (void)repeatOff
{
[o_btn_repeat setImage: o_repeat_off];
[o_btn_repeat setAlternateImage: o_repeat_single];
+ [o_btn_repeat_embed setImage: [NSImage imageNamed:@"sidebarRepeat"]];
}
- (void)shuffle
{
playlist_t *p_playlist = pl_Hold( VLCIntf );
var_Get( p_playlist, "random", &val );
[o_btn_shuffle setState: val.b_bool];
+ if(val.b_bool)
+ [o_btn_shuffle_embed setImage: [NSImage imageNamed:@"sidebarShuffleOn"]];
+ else
+ [o_btn_shuffle_embed setImage: [NSImage imageNamed:@"sidebarShuffle"]];
pl_Release( VLCIntf );
}
IBOutlet id o_btn_backward;
IBOutlet id o_btn_forward;
IBOutlet id o_btn_fullscreen;
+ IBOutlet id o_btn_equalizer;
+ IBOutlet id o_btn_playlist;
IBOutlet id o_btn_play;
- IBOutlet id o_slider;
+ IBOutlet id o_btn_prev;
+ IBOutlet id o_btn_stop;
+ IBOutlet id o_btn_next;
+ IBOutlet id o_btn_volume_down;
+ IBOutlet id o_volumeslider;
+ IBOutlet id o_btn_volume_up;
+ IBOutlet id o_timeslider;
+ IBOutlet id o_main_pgbar;
IBOutlet id o_time;
+ IBOutlet id o_scrollfield;
+ IBOutlet id o_horizontal_split;
+ IBOutlet id o_vertical_split;
+ IBOutlet id o_videosubview;
+ IBOutlet id o_sidebar_list;
IBOutlet id o_view;
+ IBOutlet id o_background_view;
+ IBOutlet id o_searchfield;
+ IBOutlet id o_status;
+ IBOutlet id o_playlist;
+ IBOutlet id o_playlist_view;
+ IBOutlet id o_playlist_table;
+ IBOutlet id o_vlc_main;
NSImage * o_img_play;
NSImage * o_img_play_pressed;
BOOL b_window_is_invisible;
NSSize videoRatio;
- int originalLevel;
+ NSInteger originalLevel;
}
- (void)controlTintChanged;
- (void)setTime: (NSString *)o_arg_ime position: (float)f_position;
+- (id)getPgbar;
- (void)playStatusUpdated: (int)i_status;
- (void)setSeekable: (BOOL)b_seekable;
+- (void)setStop:(BOOL)b_input;
+- (void)setPrev:(BOOL)b_input;
+- (void)setNext:(BOOL)b_input;
+- (void)setVolumeEnabled:(BOOL)b_input;
+
+- (void)setScrollString:(NSString *)o_string;
+
+- (void)setVolumeSlider:(float)f_level;
- (void)setVideoRatio:(NSSize)ratio;
- (NSView *)mainView;
+- (IBAction)togglePlaylist:(id)sender;
+
- (BOOL)isFullscreen;
- (void)lockFullscreenAnimation;
- (void)setFrameOnMainThread:(NSData*)packedargs;
@end
+/*****************************************************************************
+ * embeddedbackground
+ *****************************************************************************/
+
+
+@interface embeddedbackground : NSView
+{
+ IBOutlet id o_window;
+ IBOutlet id o_timeslider;
+ IBOutlet id o_main_pgbar;
+ IBOutlet id o_time;
+ IBOutlet id o_scrollfield;
+ IBOutlet id o_searchfield;
+ IBOutlet id o_btn_backward;
+ IBOutlet id o_btn_forward;
+ IBOutlet id o_btn_fullscreen;
+ IBOutlet id o_btn_equalizer;
+ IBOutlet id o_btn_playlist;
+ IBOutlet id o_btn_play;
+ IBOutlet id o_btn_prev;
+ IBOutlet id o_btn_stop;
+ IBOutlet id o_btn_next;
+ IBOutlet id o_btn_volume_down;
+ IBOutlet id o_volumeslider;
+ IBOutlet id o_btn_volume_up;
+
+ NSPoint dragStart;
+}
+
+@end
+
+/*****************************************************************************
+ * statusbar
+ *****************************************************************************/
+
+
+@interface statusbar : NSView
+{
+ IBOutlet id o_text;
+
+ BOOL mainwindow;
+}
+
+@end
\ No newline at end of file
/*****************************************************************************
* embeddedwindow.m: MacOS X interface module
*****************************************************************************
- * Copyright (C) 2005-2009 the VideoLAN team
+ * Copyright (C) 2005-2008 the VideoLAN team
* $Id$
*
* Authors: Benjamin Pracht <bigben at videolan dot org>
* Preamble
*****************************************************************************/
+/* DisableScreenUpdates, SetSystemUIMode, ... */
+#import <QuickTime/QuickTime.h>
+
#import "intf.h"
#import "controls.h"
#import "vout.h"
#import "embeddedwindow.h"
#import "fspanel.h"
+#import "playlist.h"
-/* SetSystemUIMode, ... */
-#import <Carbon/Carbon.h>
+/*****************************************************************************
+ * extension to NSWindow's interface to fix compilation warnings
+ * and let us access this functions properly
+ * this uses a private Apple-API, but works fine on all current OSX releases
+ * keep checking for compatiblity with future releases though
+ *****************************************************************************/
+
+@interface NSWindow (UndocumentedWindowProperties)
+- (void)setBottomCornerRounded: (BOOL)value;
+@end
/*****************************************************************************
* VLCEmbeddedWindow Implementation
@implementation VLCEmbeddedWindow
-- (id)initWithContentRect:(NSRect)contentRect styleMask: (NSUInteger)windowStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation
-{
- BOOL b_useTextured = YES;
- if( [[NSWindow class] instancesRespondToSelector:@selector(setContentBorderThickness:forEdge:)] )
- {
- b_useTextured = NO;
- windowStyle ^= NSTexturedBackgroundWindowMask;
- }
- self = [super initWithContentRect:contentRect styleMask:windowStyle backing:bufferingType defer:deferCreation];
- if(! b_useTextured )
- {
- [self setContentBorderThickness:28.0 forEdge:NSMinYEdge];
- }
- return self;
-}
-
- (void)awakeFromNib
{
[self setDelegate: self];
+ [self setBottomCornerRounded:NO];
+ /* button strings */
[o_btn_backward setToolTip: _NS("Rewind")];
[o_btn_forward setToolTip: _NS("Fast Forward")];
[o_btn_fullscreen setToolTip: _NS("Fullscreen")];
[o_btn_play setToolTip: _NS("Play")];
- [o_slider setToolTip: _NS("Position")];
-
- o_img_play = [NSImage imageNamed: @"play_embedded"];
- o_img_pause = [NSImage imageNamed: @"pause_embedded"];
+ [o_timeslider setToolTip: _NS("Position")];
+ [o_btn_prev setToolTip: _NS("Previous")];
+ [o_btn_stop setToolTip: _NS("Stop")];
+ [o_btn_next setToolTip: _NS("Next")];
+ [o_volumeslider setToolTip: _NS("Volume")];
+ [o_btn_playlist setToolTip: _NS("Playlist")];
+ [self setTitle: _NS("VLC media player")];
+
+ if(MACOS_VERSION < 10.5f) {
+ o_img_play = [NSImage imageNamed: @"play"];
+ o_img_pause = [NSImage imageNamed: @"pause"];
+ [o_btn_play setImage: [NSImage imageNamed: @"play"]];
+ }
+ else {
+ o_img_play = [NSImage imageNamed: @"play_big"];
+ o_img_pause = [NSImage imageNamed: @"pause_big"];
+ }
[self controlTintChanged];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector( controlTintChanged )
name: NSControlTintDidChangeNotification
object: nil];
+ /* Set color of sidebar to Leopard's "Sidebar Blue" */
+ [o_sidebar_list setBackgroundColor: [NSColor colorWithCalibratedRed:0.820
+ green:0.843
+ blue:0.886
+ alpha:1.0]];
+
+ [self setMinSize:NSMakeSize([o_sidebar_list convertRect:[o_sidebar_list bounds]
+ toView: nil].size.width + 551., 114.)];
+
/* Useful to save o_view frame in fullscreen mode */
o_temp_view = [[NSView alloc] init];
[o_temp_view setAutoresizingMask:NSViewHeightSizable | NSViewWidthSizable];
[o_btn_fullscreen setState: NO];
b_fullscreen = NO;
- [self setMovableByWindowBackground:YES];
-
- [self setDelegate:self];
-
/* Make sure setVisible: returns NO */
[self orderOut:self];
- b_window_is_invisible = YES;
+ //b_window_is_invisible = YES;
videoRatio = NSMakeSize( 0., 0. );
}
if( [o_btn_play alternateImage] == o_img_play_pressed )
b_playing = YES;
- if( [NSColor currentControlTint] == NSGraphiteControlTint )
- {
- o_img_play_pressed = [NSImage imageNamed: @"play_embedded_graphite"];
- o_img_pause_pressed = [NSImage imageNamed: @"pause_embedded_graphite"];
- [o_btn_backward setAlternateImage: [NSImage imageNamed: @"skip_previous_embedded_graphite"]];
- [o_btn_forward setAlternateImage: [NSImage imageNamed: @"skip_forward_embedded_graphite"]];
- [o_btn_fullscreen setAlternateImage: [NSImage imageNamed: @"fullscreen_graphite"]];
+ if (MACOS_VERSION < 10.5f) {
+ /* System is running Tiger and should use aqua buttons */
+ [o_btn_backward setImage: [NSImage imageNamed: @"skip_previous_active"]];
+ [o_btn_forward setImage: [NSImage imageNamed: @"skip_forward_active"]];
+ if( [NSColor currentControlTint] == NSGraphiteControlTint )
+ {
+ o_img_play_pressed = [NSImage imageNamed: @"play_graphite"];
+ o_img_pause_pressed = [NSImage imageNamed: @"pause_graphite"];
+ [o_btn_backward setAlternateImage: [NSImage imageNamed: @"skip_previous_graphite"]];
+ [o_btn_forward setAlternateImage: [NSImage imageNamed: @"skip_forward_graphite"]];
+ }
+ else
+ {
+ o_img_play_pressed = [NSImage imageNamed: @"play_blue"];
+ o_img_pause_pressed = [NSImage imageNamed: @"pause_blue"];
+ [o_btn_backward setAlternateImage: [NSImage imageNamed: @"skip_previous_blue"]];
+ [o_btn_forward setAlternateImage: [NSImage imageNamed: @"skip_forward_blue"]];
+ }
}
- else
- {
- o_img_play_pressed = [NSImage imageNamed: @"play_embedded_blue"];
- o_img_pause_pressed = [NSImage imageNamed: @"pause_embedded_blue"];
- [o_btn_backward setAlternateImage: [NSImage imageNamed: @"skip_previous_embedded_blue"]];
- [o_btn_forward setAlternateImage: [NSImage imageNamed: @"skip_forward_embedded_blue"]];
- [o_btn_fullscreen setAlternateImage: [NSImage imageNamed: @"fullscreen_blue"]];
+ else{
+ /* System is running Leopard or later and should use metal buttons */
+ o_img_play_pressed = [NSImage imageNamed: @"play_big_down"];
+ o_img_pause_pressed = [NSImage imageNamed: @"pause_big_down"];
}
if( b_playing )
- (void)setTime:(NSString *)o_arg_time position:(float)f_position
{
[o_time setStringValue: o_arg_time];
- [o_slider setFloatValue: f_position];
+ [o_timeslider setFloatValue: f_position];
}
- (void)playStatusUpdated:(int)i_status
{
[o_btn_forward setEnabled: b_seekable];
[o_btn_backward setEnabled: b_seekable];
- [o_slider setEnabled: b_seekable];
+ [o_timeslider setEnabled: b_seekable];
+}
+
+- (void)setScrollString:(NSString *)o_string
+{
+ [o_scrollfield setStringValue: o_string];
+}
+
+- (id)getPgbar
+{
+ if( o_main_pgbar )
+ return o_main_pgbar;
+
+ return nil;
+}
+
+- (void)setStop:(BOOL)b_input
+{
+ [o_btn_stop setEnabled: b_input];
+}
+
+- (void)setNext:(BOOL)b_input
+{
+ [o_btn_next setEnabled: b_input];
+}
+
+- (void)setPrev:(BOOL)b_input
+{
+ [o_btn_prev setEnabled: b_input];
+}
+
+- (void)setVolumeEnabled:(BOOL)b_input
+{
+ [o_volumeslider setEnabled: b_input];
+}
+
+- (void)setVolumeSlider:(float)f_level
+{
+ [o_volumeslider setFloatValue: f_level];
}
- (BOOL)windowShouldZoom:(NSWindow *)sender toFrame:(NSRect)newFrame
{
playlist_t * p_playlist = pl_Hold( VLCIntf );
- playlist_Stop( p_playlist );
+ /* Only want to stop playback if video is playing */
+ if( videoRatio.height != 0. && videoRatio.width != 0. )
+ playlist_Stop( p_playlist );
pl_Release( VLCIntf );
return YES;
}
- (NSSize)windowWillResize:(NSWindow *)window toSize:(NSSize)proposedFrameSize
{
+ NSView *playlist_area = [[o_vertical_split subviews] objectAtIndex:1];
+ NSRect newList = [playlist_area frame];
+ if( newList.size.height < 50 && newList.size.height > 0 ) {
+ [self togglePlaylist:self];
+ }
+
+ /* With no video open or with the playlist open the behavior is odd */
+ if( newList.size.height > 50 )
+ return proposedFrameSize;
+
if( videoRatio.height == 0. || videoRatio.width == 0. )
return proposedFrameSize;
NSRect contentRect = [self contentRectForFrameRect:[self frame]];
float marginy = viewRect.origin.y + [self frame].size.height - contentRect.size.height;
float marginx = contentRect.size.width - viewRect.size.width;
+
proposedFrameSize.height = (proposedFrameSize.width - marginx) * videoRatio.height / videoRatio.width + marginy;
return proposedFrameSize;
}
+- (void)becomeMainWindow
+{
+ [o_sidebar_list setBackgroundColor: [NSColor colorWithCalibratedRed:0.820
+ green:0.843
+ blue:0.886
+ alpha:1.0]];
+ [o_status becomeMainWindow];
+ [super becomeMainWindow];
+}
+
+- (void)resignMainWindow
+{
+ [o_sidebar_list setBackgroundColor: [NSColor colorWithCalibratedWhite:0.91 alpha:1.0]];
+ [o_status resignMainWindow];
+ [super resignMainWindow];
+}
+
+- (float)splitView:(NSSplitView *) splitView constrainSplitPosition:(float) proposedPosition ofSubviewAt:(int) index
+{
+ if([splitView isVertical])
+ return proposedPosition;
+ else {
+ float bottom = [splitView frame].size.height - [splitView dividerThickness];
+ if(proposedPosition > bottom - 50) {
+ [o_btn_playlist setState: NSOffState];
+ [o_searchfield setHidden:YES];
+ [o_playlist_view setHidden:YES];
+ return bottom;
+ }
+ else {
+ [o_btn_playlist setState: NSOnState];
+ [o_searchfield setHidden:NO];
+ [o_playlist_view setHidden:NO];
+ [o_playlist swapPlaylists: o_playlist_table];
+ [o_vlc_main togglePlaylist:self];
+ return proposedPosition;
+ }
+ }
+}
+
+- (void)splitViewWillResizeSubviews:(NSNotification *) notification
+{
+
+}
+
+- (float)splitView:(NSSplitView *) splitView constrainMinCoordinate:(float) proposedMin ofSubviewAt:(int) offset
+{
+ if([splitView isVertical])
+ return 125.;
+ else
+ return 0.;
+}
+
+- (float)splitView:(NSSplitView *) splitView constrainMaxCoordinate:(float) proposedMax ofSubviewAt:(int) offset
+{
+ if([splitView isVertical])
+ return MIN([self frame].size.width - 551, 300);
+ else
+ return [splitView frame].size.height;
+}
+
+- (BOOL)splitView:(NSSplitView *) splitView canCollapseSubview:(NSView *) subview
+{
+ if([splitView isVertical])
+ return NO;
+ else
+ return NO;
+}
+
+- (NSRect)splitView:(NSSplitView *)splitView effectiveRect:(NSRect)proposedEffectiveRect forDrawnRect:(NSRect)drawnRect
+ ofDividerAtIndex:(NSInteger)dividerIndex
+{
+ if([splitView isVertical]) {
+ drawnRect.origin.x -= 3;
+ drawnRect.size.width += 5;
+ return drawnRect;
+ }
+ else
+ return drawnRect;
+}
+
+- (IBAction)togglePlaylist:(id)sender
+{
+ NSView *playback_area = [[o_vertical_split subviews] objectAtIndex:0];
+ NSView *playlist_area = [[o_vertical_split subviews] objectAtIndex:1];
+ NSRect newVid = [playback_area frame];
+ NSRect newList = [playlist_area frame];
+ if(newList.size.height < 50 && sender != self && sender != o_vlc_main) {
+ newList.size.height = newVid.size.height/2;
+ newVid.size.height = newVid.size.height/2;
+ newVid.origin.y = newVid.origin.y + newList.size.height;
+ [o_btn_playlist setState: NSOnState];
+ [o_searchfield setHidden:NO];
+ [o_playlist_view setHidden:NO];
+ [o_playlist swapPlaylists: o_playlist_table];
+ [o_vlc_main togglePlaylist:self];
+ }
+ else {
+ newVid.size.height = newVid.size.height + newList.size.height;
+ newList.size.height = 0;
+ newVid.origin.y = 0;
+ [o_btn_playlist setState: NSOffState];
+ [o_searchfield setHidden:YES];
+ [o_playlist_view setHidden:YES];
+ }
+ [playback_area setFrame: newVid];
+ [playlist_area setFrame: newList];
+}
+
/*****************************************************************************
* Fullscreen support
*/
[o_fullscreen_window setBackgroundColor: [NSColor blackColor]];
[o_fullscreen_window setCanBecomeKeyWindow: YES];
- if (![self isVisible] || [self alphaValue] == 0.0)
+ if (![self isVisible] || [self alphaValue] == 0.0 || MACOS_VERSION < 10.4f)
{
- /* We don't animate if we are not visible, instead we
+ /* We don't animate if we are not visible or if we are running on
+ * Mac OS X <10.4 which doesn't support NSAnimation, instead we
* simply fade the display */
CGDisplayFadeReservationToken token;
[o_temp_view setFrame:[o_view frame]];
[o_fullscreen_window setContentView:o_view];
+ [o_fullscreen_window makeKeyAndOrderFront:self];
+
[o_fullscreen_window makeKeyAndOrderFront:self];
[o_fullscreen_window orderFront:self animate:YES];
}
/* Make sure we don't see the o_view disappearing of the screen during this operation */
- NSDisableScreenUpdates();
- [[self contentView] replaceSubview:o_view with:o_temp_view];
+ DisableScreenUpdates();
+ [[self contentView] replaceSubview:o_view with:o_temp_view];
[o_temp_view setFrame:[o_view frame]];
[o_fullscreen_window setContentView:o_view];
[o_fullscreen_window makeKeyAndOrderFront:self];
- NSEnableScreenUpdates();
+ EnableScreenUpdates();
+ }
+
+ if (MACOS_VERSION < 10.4f)
+ {
+ /* We were already fullscreen nothing to do when NSAnimation
+ * is not supported */
+ [self unlockFullscreenAnimation];
+ return;
}
/* We are in fullscreen (and no animation is running) */
return;
}
- if (fadeout)
+ if (fadeout || MACOS_VERSION < 10.4f)
{
- /* We don't animate if we are not visible, instead we
+ /* We don't animate if we are not visible or if we are running on
+ * Mac OS X <10.4 which doesn't support NSAnimation, instead we
* simply fade the display */
CGDisplayFadeReservationToken token;
{
/* 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 */
- NSDisableScreenUpdates();
+ DisableScreenUpdates();
[o_view retain];
[o_view removeFromSuperviewWithoutNeedingDisplay];
[[self contentView] replaceSubview:o_temp_view with:o_view];
if ([self isVisible])
[super makeKeyAndOrderFront:self]; /* our version contains a workaround */
[o_fullscreen_window orderOut: self];
- NSEnableScreenUpdates();
+ EnableScreenUpdates();
[o_fullscreen_window release];
o_fullscreen_window = nil;
}
@end
+
+/*****************************************************************************
+ * embeddedbackground
+ *****************************************************************************/
+
+
+@implementation embeddedbackground
+
+- (void)dealloc
+{
+ [self unregisterDraggedTypes];
+ [super dealloc];
+}
+
+- (void)awakeFromNib
+{
+ [self registerForDraggedTypes:[NSArray arrayWithObjects:NSTIFFPboardType,
+ NSFilenamesPboardType, nil]];
+ [self addSubview: o_timeslider];
+ [self addSubview: o_scrollfield];
+ [self addSubview: o_time];
+ [self addSubview: o_main_pgbar];
+ [self addSubview: o_btn_backward];
+ [self addSubview: o_btn_forward];
+ [self addSubview: o_btn_fullscreen];
+ [self addSubview: o_btn_equalizer];
+ [self addSubview: o_btn_playlist];
+ [self addSubview: o_btn_play];
+ [self addSubview: o_btn_prev];
+ [self addSubview: o_btn_stop];
+ [self addSubview: o_btn_next];
+ [self addSubview: o_btn_volume_down];
+ [self addSubview: o_volumeslider];
+ [self addSubview: o_btn_volume_up];
+ [self addSubview: o_searchfield];
+}
+
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+{
+ if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
+ == NSDragOperationGeneric)
+ {
+ return NSDragOperationGeneric;
+ }
+ else
+ {
+ return NSDragOperationNone;
+ }
+}
+
+- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
+{
+ return YES;
+}
+
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+ NSPasteboard *o_paste = [sender draggingPasteboard];
+ NSArray *o_types = [NSArray arrayWithObjects: NSFilenamesPboardType, nil];
+ NSString *o_desired_type = [o_paste availableTypeFromArray:o_types];
+ NSData *o_carried_data = [o_paste dataForType:o_desired_type];
+ BOOL b_autoplay = config_GetInt( VLCIntf, "macosx-autoplay" );
+
+ if( o_carried_data )
+ {
+ if ([o_desired_type isEqualToString:NSFilenamesPboardType])
+ {
+ int i;
+ NSArray *o_array = [NSArray array];
+ NSArray *o_values = [[o_paste propertyListForType: NSFilenamesPboardType]
+ sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
+
+ for( i = 0; i < (int)[o_values count]; i++)
+ {
+ NSDictionary *o_dic;
+ o_dic = [NSDictionary dictionaryWithObject:[o_values objectAtIndex:i] forKey:@"ITEM_URL"];
+ o_array = [o_array arrayByAddingObject: o_dic];
+ }
+ if( b_autoplay )
+ [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:NO];
+ else
+ [[[VLCMain sharedInstance] playlist] appendArray: o_array atPos: -1 enqueue:YES];
+ return YES;
+ }
+ }
+ [self setNeedsDisplay:YES];
+ return YES;
+}
+
+- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
+{
+ [self setNeedsDisplay:YES];
+}
+
+- (void)drawRect:(NSRect)rect
+{
+ NSImage *leftImage = [NSImage imageNamed:@"display_left"];
+ NSImage *middleImage = [NSImage imageNamed:@"display_middle"];
+ NSImage *rightImage = [NSImage imageNamed:@"display_right"];
+ [middleImage setSize:NSMakeSize(NSWidth( [self bounds] ) - 134 - [leftImage size].width - [rightImage size].width, [middleImage size].height)];
+ [middleImage setScalesWhenResized:YES];
+ [leftImage compositeToPoint:NSMakePoint( 122., 40. ) operation:NSCompositeSourceOver];
+ [middleImage compositeToPoint:NSMakePoint( 122. + [leftImage size].width, 40. ) operation:NSCompositeSourceOver];
+ [rightImage compositeToPoint:NSMakePoint( NSWidth( [self bounds] ) - 12 - [rightImage size].width, 40. ) operation:NSCompositeSourceOver];
+}
+
+- (void)mouseDown:(NSEvent *)event
+{
+ dragStart = [self convertPoint:[event locationInWindow] fromView:nil];
+}
+
+- (void)mouseDragged:(NSEvent *)event
+{
+ NSPoint dragLocation = [self convertPoint:[event locationInWindow] fromView:nil];
+ NSPoint winOrigin = [o_window frame].origin;
+
+ NSPoint newOrigin = NSMakePoint(winOrigin.x + (dragLocation.x - dragStart.x),
+ winOrigin.y + (dragLocation.y - dragStart.y));
+ [o_window setFrameOrigin: newOrigin];
+}
+
+@end
+
+/*****************************************************************************
+ * statusbar
+ *****************************************************************************/
+
+
+@implementation statusbar
+- (void)awakeFromNib
+{
+ [self addSubview: o_text];
+ mainwindow = YES;
+}
+
+- (void)resignMainWindow
+{
+ mainwindow = NO;
+ [self needsDisplay];
+}
+
+- (void)becomeMainWindow
+{
+ mainwindow = YES;
+ [self needsDisplay];
+}
+
+- (void)drawRect:(NSRect)rect
+{
+ if(mainwindow)
+ [[NSColor colorWithCalibratedRed:0.820
+ green:0.843
+ blue:0.886
+ alpha:1.0] set];
+ else
+ [[NSColor colorWithCalibratedWhite:0.91 alpha:1.0] set];
+ NSRectFill(rect);
+ /*NSRect divider = rect;
+ divider.origin.y += divider.size.height - 1;
+ divider.size.height = 1;
+ [[NSColor colorWithCalibratedWhite:0.65 alpha:1.] set];
+ NSRectFill(divider);*/
+}
+@end
@interface VLCEqualizer : NSObject
{
IBOutlet id o_btn_equalizer;
+ IBOutlet id o_btn_equalizer_embedded;
IBOutlet id o_ckb_2pass;
IBOutlet id o_ckb_enable;
IBOutlet id o_fld_preamp;
{
int i;
[o_btn_equalizer setToolTip: _NS("Equalizer")];
+ [o_btn_equalizer_embedded setToolTip: _NS("Equalizer")];
[o_ckb_2pass setTitle: _NS("2 Pass")];
[o_ckb_2pass setToolTip: _NS("Apply the "
"equalizer filter twice. The effect will be sharper.")];
{
[o_window orderOut:sender];
[o_btn_equalizer setState:NSOffState];
+ [o_btn_equalizer_embedded setState:NSOffState];
}
else
{
[o_window makeKeyAndOrderFront:sender];
[o_btn_equalizer setState:NSOnState];
+ [o_btn_equalizer_embedded setState:NSOnState];
}
}
IBOutlet NSMenu * o_mu_window;
IBOutlet NSMenuItem * o_mi_minimize;
IBOutlet NSMenuItem * o_mi_close_window;
+ IBOutlet NSMenuItem * o_mi_player;
IBOutlet NSMenuItem * o_mi_controller;
IBOutlet NSMenuItem * o_mi_equalizer;
IBOutlet NSMenuItem * o_mi_extended;
[o_mu_window setTitle: _NS("Window")];
[o_mi_minimize setTitle: _NS("Minimize Window")];
[o_mi_close_window setTitle: _NS("Close Window")];
+ [o_mi_player setTitle: _NS("Player...")];
[o_mi_controller setTitle: _NS("Controller...")];
[o_mi_equalizer setTitle: _NS("Equalizer...")];
[o_mi_extended setTitle: _NS("Extended Controls...")];
}
[o_btn_stop setEnabled: b_input];
+ [o_embedded_window setStop: b_input];
[o_btn_ff setEnabled: b_seekable];
[o_btn_rewind setEnabled: b_seekable];
[o_btn_prev setEnabled: (b_plmul || b_chapters)];
+ [o_embedded_window setPrev: (b_plmul || b_chapters)];
[o_btn_next setEnabled: (b_plmul || b_chapters)];
+ [o_embedded_window setNext: (b_plmul || b_chapters)];
[o_timeslider setFloatValue: 0.0];
[o_timeslider setEnabled: b_seekable];
[[[self controls] fspanel] setSeekable: b_seekable];
[o_embedded_window setSeekable: b_seekable];
+ [o_embedded_window setTime:@"00:00" position:0.0];
p_intf->p_sys->b_current_title_update = true;
i_volume_step = config_GetInt( p_intf->p_libvlc, "volume-step" );
[o_volumeslider setFloatValue: (float)i_lastShownVolume / i_volume_step];
[o_volumeslider setEnabled: TRUE];
+ [o_embedded_window setVolumeSlider: (float)i_lastShownVolume / i_volume_step];
+ [o_embedded_window setVolumeEnabled: TRUE];
[[[self controls] fspanel] setVolumeLevel: (float)i_lastShownVolume / i_volume_step];
p_intf->p_sys->b_mute = ( i_lastShownVolume == 0 );
p_intf->p_sys->b_volume_update = FALSE;
IBOutlet id o_tc_duration;
IBOutlet id o_outline_view;
+ IBOutlet id o_tc_name_other;
+ IBOutlet id o_tc_author_other;
+ IBOutlet id o_tc_duration_other;
+ IBOutlet id o_outline_view_other;
+
NSMutableDictionary *o_outline_dict;
}
- (void)initStrings;
- (playlist_item_t *)selectedPlaylistItem;
- (NSOutlineView *)outlineView;
-
+- (void)swapPlaylists:(id)newList;
@end
/*****************************************************************************
IBOutlet id o_btn_playlist;
IBOutlet id o_playlist_view;
+ IBOutlet id o_sidebar;
IBOutlet id o_status_field;
+ IBOutlet id o_status_field_embed;
IBOutlet id o_search_field;
+ IBOutlet id o_search_field_other;
IBOutlet id o_mi_save_playlist;
IBOutlet id o_ctx_menu;
- (IBAction)addNode:(id)sender;
+- (void)playSidebarItem:(id)item;
+- (id)playingItem;
+
- (void)appendArray:(NSArray*)o_array atPos:(int)i_position enqueue:(BOOL)b_enqueue;
- (void)appendNodeArray:(NSArray*)o_array inNode:(playlist_item_t *)p_node atPos:(int)i_position enqueue:(BOOL)b_enqueue;
#import "controls.h"
#import "vlc_osd.h"
#import "misc.h"
+#import "sidebarview.h"
#import <vlc_interface.h>
#import <vlc_services_discovery.h>
[o_outline_view setAllowsEmptySelection: NO];
[o_outline_view expandItem: [o_outline_view itemAtRow:0]];
+ [o_outline_view_other setTarget: self];
+ [o_outline_view_other setDelegate: self];
+ [o_outline_view_other setDataSource: self];
+ [o_outline_view_other setAllowsEmptySelection: NO];
+
pl_Release( VLCIntf );
[self initStrings];
}
[[o_tc_name headerCell] setStringValue:_NS("Name")];
[[o_tc_author headerCell] setStringValue:_NS("Author")];
[[o_tc_duration headerCell] setStringValue:_NS("Duration")];
+
+ [[o_tc_name_other headerCell] setStringValue:_NS("Name")];
+ [[o_tc_author_other headerCell] setStringValue:_NS("Author")];
+ [[o_tc_duration_other headerCell] setStringValue:_NS("Duration")];
+}
+
+- (void)swapPlaylists:(id)newList
+{
+ if(newList != o_outline_view)
+ {
+ id o_outline_view_temp = o_outline_view;
+ id o_tc_author_temp = o_tc_author;
+ id o_tc_duration_temp = o_tc_duration;
+ id o_tc_name_temp = o_tc_name;
+ o_outline_view = o_outline_view_other;
+ o_tc_author = o_tc_author_other;
+ o_tc_duration = o_tc_duration_other;
+ o_tc_name = o_tc_name_other;
+ o_outline_view_other = o_outline_view_temp;
+ o_tc_author_other = o_tc_author_temp;
+ o_tc_duration_other = o_tc_duration_temp;
+ o_tc_name_other = o_tc_name_temp;
+ }
}
- (NSOutlineView *)outlineView
[super awakeFromNib];
[o_outline_view setDoubleAction: @selector(playItem:)];
+ [o_outline_view_other setDoubleAction: @selector(playItem:)];
[o_outline_view registerForDraggedTypes:
[NSArray arrayWithObjects: NSFilenamesPboardType,
@"VLCPlaylistItemPboardType", nil]];
[o_outline_view setIntercellSpacing: NSMakeSize (0.0, 1.0)];
+ [o_outline_view_other registerForDraggedTypes:
+ [NSArray arrayWithObjects: NSFilenamesPboardType,
+ @"VLCPlaylistItemPboardType", nil]];
+ [o_outline_view_other setIntercellSpacing: NSMakeSize (0.0, 1.0)];
+
/* This uses private Apple API which works fine until 10.5.
* We need to keep checking in the future!
* These methods are being added artificially to NSOutlineView's interface above */
[o_mi_services setTitle: _NS("Services discovery")];
[o_mm_mi_services setTitle: _NS("Services discovery")];
[o_status_field setStringValue: _NS("No items in the playlist")];
+ [o_status_field_embed setStringValue: _NS("No items in the playlist")];
[o_search_field setToolTip: _NS("Search in Playlist")];
+ [o_search_field_other setToolTip: _NS("Search in Playlist")];
[o_mi_addNode setTitle: _NS("Add Folder to Playlist")];
[o_save_accessory_text setStringValue: _NS("File Format:")];
[[o_save_accessory_popup itemAtIndex:2] setTitle: _NS("HTML Playlist")];
}
+- (void)swapPlaylists:(id)newList
+{
+ if(newList != o_outline_view)
+ {
+ id o_search_field_temp = o_search_field;
+ o_search_field = o_search_field_other;
+ o_search_field_other = o_search_field_temp;
+ [super swapPlaylists:newList];
+ [self playlistUpdated];
+ }
+}
+
- (void)playlistUpdated
{
/* Clear indications of any existing column sorting */
// TODO Find a way to keep the dict size to a minimum
//[o_outline_dict removeAllObjects];
[o_outline_view reloadData];
+ [o_sidebar updateSidebar:[self playingItem]];
[[[[VLCMain sharedInstance] wizard] playlistWizard] reloadOutlineView];
[[[[VLCMain sharedInstance] bookmarks] dataTable] reloadData];
[o_status_field setStringValue: [NSString stringWithFormat:
_NS("%i items"),
playlist_CurrentSize( p_playlist )]];
+ [o_status_field_embed setStringValue: [NSString stringWithFormat:
+ _NS("%i items"),
+ playlist_CurrentSize( p_playlist )]];
}
else
{
if( playlist_IsEmpty( p_playlist ) )
+ {
[o_status_field setStringValue: _NS("No items in the playlist")];
+ [o_status_field_embed setStringValue: _NS("No items in the playlist")];
+ }
else
+ {
[o_status_field setStringValue: _NS("1 item")];
+ [o_status_field_embed setStringValue: _NS("1 item")];
+ }
}
PL_UNLOCK;
pl_Release( VLCIntf );
pl_Release( p_intf );
}
+- (void)playSidebarItem:(id)item
+{
+ intf_thread_t * p_intf = VLCIntf;
+ playlist_t * p_playlist = pl_Hold( p_intf );
+
+ playlist_item_t *p_item;
+ playlist_item_t *p_node = NULL;
+
+ p_item = [item pointerValue];
+
+ if( p_item )
+ {
+ if( p_item->i_children == -1 )
+ {
+ p_node = p_item->p_parent;
+
+ }
+ else
+ {
+ p_node = p_item;
+ if( p_node->i_children > 0 && p_node->pp_children[0]->i_children == -1 )
+ {
+ p_item = p_node->pp_children[0];
+ }
+ else
+ {
+ p_item = NULL;
+ }
+ }
+ playlist_Control( p_playlist, PLAYLIST_VIEWPLAY, pl_Unlocked, p_node, p_item );
+ }
+ pl_Release( p_intf );
+}
+
- (IBAction)revealItemInFinder:(id)sender
{
playlist_item_t * p_item = [[o_outline_view itemAtRow:[o_outline_view selectedRow]] pointerValue];
pl_Release( VLCIntf );
}
+- (id)playingItem
+{
+ playlist_t *p_playlist = pl_Hold( VLCIntf );
+
+ id o_playing_item;
+
+ o_playing_item = [o_outline_dict objectForKey:
+ [NSString stringWithFormat:@"%p", playlist_CurrentPlayingItem( p_playlist )]];
+
+ pl_Release( VLCIntf );
+
+ return o_playing_item;
+}
+
- (IBAction)addNode:(id)sender
{
playlist_t * p_playlist = pl_Hold( VLCIntf );
[o_status_field setStringValue: [NSString stringWithFormat:
_NS("%i items"),
playlist_CurrentSize( p_playlist )]];
+ [o_status_field_embed setStringValue: [NSString stringWithFormat:
+ _NS("%i items"),
+ playlist_CurrentSize( p_playlist )]];
}
else
{
if( playlist_IsEmpty( p_playlist ) )
{
[o_status_field setStringValue: _NS("No items in the playlist")];
+ [o_status_field_embed setStringValue: _NS("No items in the playlist")];
}
else
{
[o_status_field setStringValue: _NS("1 item")];
+ [o_status_field_embed setStringValue: _NS("1 item")];
}
}
PL_UNLOCK;
--- /dev/null
+/*****************************************************************************
+ * sidebarview.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2005-2008 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Eric Dudiak <dudiak at gmail dot com>
+ * Colloquy <http://colloquy.info/>
+ *
+ * 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 sidebarview : NSSplitView
+{
+ long _mainSubviewIndex;
+}
+@end
+
+/*****************************************************************************
+ * VLCSidebar interface
+ *****************************************************************************/
+@interface VLCSidebar : NSObject
+{
+ IBOutlet id o_outline_view;
+ IBOutlet id o_playlist;
+}
+
+- (NSOutlineView *)outlineView;
+- (void)updateSidebar:(id)item;
+
+@end
\ No newline at end of file
--- /dev/null
+/*****************************************************************************
+ * sidebarview.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2005-2008 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Eric Dudiak <dudiak at gmail dot com>
+ * Colloquy <http://colloquy.info/>
+ *
+ * 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 "sidebarview.h"
+#import "intf.h"
+#import "playlist.h"
+
+@implementation sidebarview
+- (void) resetCursorRects
+{
+ if( ! [self isPaneSplitter] )
+ [super resetCursorRects];
+}
+
+- (id) initWithCoder:(NSCoder *) decoder {
+ if( ( self = [super initWithCoder:decoder] ) )
+ _mainSubviewIndex = 1;
+ return self;
+}
+
+- (float) dividerThickness
+{
+ return 1.0;
+}
+
+- (BOOL) isVertical
+{
+ return YES;
+}
+
+- (void) drawDividerInRect:(NSRect) rect
+{
+ [[NSColor colorWithCalibratedWhite:0.65 alpha:1.] set];
+ NSRectFill( rect );
+}
+
+- (void) adjustSubviews
+{
+ if( _mainSubviewIndex == -1 || [[self subviews] count] != 2 ) {
+ [super adjustSubviews];
+ return;
+ }
+
+ float dividerThickness = [self dividerThickness];
+ NSRect newFrame = [self frame];
+
+ NSView *mainView = [[self subviews] objectAtIndex:_mainSubviewIndex];
+ NSView *otherView = ( _mainSubviewIndex ? [[self subviews] objectAtIndex:0] : [[self subviews] objectAtIndex:1] );
+
+ NSRect mainFrame = [mainView frame];
+ NSRect otherFrame = [otherView frame];
+
+
+ mainFrame.size.width = NSWidth( newFrame ) - dividerThickness - NSWidth( otherFrame );
+ mainFrame.size.height = NSHeight( newFrame );
+ mainFrame.origin.x = ( _mainSubviewIndex ? NSWidth( otherFrame ) + dividerThickness : 0. );
+ mainFrame.origin.y = 0.;
+
+ otherFrame.size.width = NSWidth( otherFrame );
+ otherFrame.size.height = NSHeight( newFrame );
+ otherFrame.origin.x = ( _mainSubviewIndex ? 0. : NSWidth( mainFrame ) + dividerThickness );
+ otherFrame.origin.y = 0.;
+
+ [mainView setFrame:mainFrame];
+ [otherView setFrame:otherFrame];
+
+ [self setNeedsDisplay:YES];
+}
+@end
+
+/*****************************************************************************
+ * VLCPlaylist implementation
+ *****************************************************************************/
+@implementation VLCSidebar
+
+- (void)awakeFromNib
+{
+ [o_outline_view setTarget: self];
+ [o_outline_view setDelegate: self];
+ [o_outline_view setDataSource: self];
+ [o_outline_view setAllowsEmptySelection: NO];
+}
+
+- (NSOutlineView *)outlineView
+{
+ return o_outline_view;
+}
+
+- (void)outlineView:(NSOutlineView *)outlineView
+ willDisplayCell:(id)cell
+ forTableColumn:(NSTableColumn *)tableColumn
+ item:(id)item
+{
+ if ( ![outlineView isExpandable:item] )
+ {
+ [cell setFont: [NSFont systemFontOfSize: 12]];
+ [cell setTextColor:[NSColor blackColor]];
+ }
+ else
+ {
+ [cell setFont: [NSFont boldSystemFontOfSize: 10]];
+ [cell setTextColor:[NSColor colorWithCalibratedWhite:0.365 alpha:1.0]];
+ }
+}
+
+- (void)updateSidebar:(id)item
+{
+ int i_row = -1;
+ [o_outline_view reloadData];
+ i_row = [o_outline_view rowForItem:item];
+ if( i_row > -1 )
+ {
+ [o_outline_view selectRow:i_row byExtendingSelection: NO];
+ [o_outline_view scrollRowToVisible: i_row];
+ }
+}
+
+- (CGFloat)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item
+{
+ if( [outlineView isExpandable:item] )
+ return 12.;
+ else
+ return 20.;
+}
+
+- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
+{
+ if( [outlineView isExpandable:item] )
+ return NO;
+ else
+ {
+ if( ![[o_playlist playingItem] isEqual: item] )
+ [o_playlist playSidebarItem:item];
+ return YES;
+ }
+}
+
+- (void)outlineViewItemDidExpand:(NSNotification *)notification
+{
+ int i_row = -1;
+ i_row = [o_outline_view rowForItem:[o_playlist playingItem]];
+ if( i_row > -1 )
+ {
+ [o_outline_view selectRow:i_row byExtendingSelection: NO];
+ [o_outline_view scrollRowToVisible: i_row];
+ }
+}
+
+@end
+
+@implementation VLCSidebar (NSOutlineViewDataSource)
+
+/* return the number of children for Obj-C pointer item */ /* DONE */
+- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
+{
+ return [o_playlist outlineView:outlineView numberOfChildrenOfItem:item];
+}
+
+/* return the child at index for the Obj-C pointer item */ /* DONE */
+- (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
+{
+ return [o_playlist outlineView:outlineView child:index ofItem:item];
+}
+
+/* is the item expandable */
+- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
+{
+ return [o_playlist outlineView:outlineView isItemExpandable:item];
+}
+
+/* retrieve the string values for the cells */
+- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)o_tc byItem:(id)item
+{
+ if( [outlineView isExpandable:item] )
+ return [[o_playlist outlineView:outlineView objectValueForTableColumn:o_tc byItem:item] uppercaseString];
+ else
+ return [o_playlist outlineView:outlineView objectValueForTableColumn:o_tc byItem:item];
+}
+
+@end
--- /dev/null
+/*****************************************************************************
+ * sidestatusview.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2005-2008 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Eric Dudiak <dudiak at gmail dot com>
+ * Colloquy <http://colloquy.info/>
+ *
+ * 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 sidestatusview : NSView {
+ IBOutlet NSSplitView *splitView;
+ float _clickOffset;
+ BOOL _insideResizeArea;
+}
+
+@end
--- /dev/null
+/*****************************************************************************
+ * sidestatusview.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2005-2008 the VideoLAN team
+ * $Id$
+ *
+ * Authors: Eric Dudiak <dudiak at gmail dot com>
+ * Colloquy <http://colloquy.info/>
+ *
+ * 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 "sidestatusview.h"
+
+@implementation sidestatusview
+-(void)resetCursorRects
+{
+ [super resetCursorRects];
+ if( ! splitView ) return;
+
+ NSImage *resizeImage = [NSImage imageNamed:@"sidebarResizeWidget"];
+ NSRect location;
+ location.size = [resizeImage size];
+ location.origin = NSMakePoint( NSWidth( [self bounds] ) - [resizeImage size].width, 0. );
+ [self addCursorRect:location cursor:[NSCursor resizeLeftRightCursor]];
+}
+
+- (void)drawRect:(NSRect)rect
+{
+ NSImage *backgroundImage = [NSImage imageNamed:@"sidebarStatusAreaBackground"];
+ [backgroundImage setSize:NSMakeSize(NSWidth( [self bounds] ), [backgroundImage size].height)];
+ [backgroundImage setScalesWhenResized:YES];
+ [backgroundImage compositeToPoint:NSMakePoint( 0., 0. ) operation:NSCompositeCopy];
+
+ if( splitView ) {
+ NSImage *resizeImage = [NSImage imageNamed:@"sidebarResizeWidget"];
+ [resizeImage compositeToPoint:NSMakePoint( NSWidth( [self bounds] ) - [resizeImage size].width, 0. ) operation:NSCompositeCopy];
+ }
+}
+
+- (void)mouseDown:(NSEvent *)event
+{
+ if( ! splitView ) return;
+ NSPoint clickLocation = [self convertPoint:[event locationInWindow] fromView:nil];
+
+ NSImage *resizeImage = [NSImage imageNamed:@"sidebarResizeWidget"];
+ NSRect location;
+ location.size = [resizeImage size];
+ location.origin = NSMakePoint( NSWidth( [self bounds] ) - [resizeImage size].width, 0. );
+
+ _insideResizeArea = ( NSPointInRect( clickLocation, location ) );
+ if( ! _insideResizeArea ) return;
+
+ clickLocation = [self convertPoint:[event locationInWindow] fromView:[self superview]];
+ _clickOffset = NSWidth( [[self superview] frame] ) - clickLocation.x;
+}
+
+- (void)mouseDragged:(NSEvent *)event
+{
+ if( ! splitView || ! _insideResizeArea ) return;
+
+ [[NSNotificationCenter defaultCenter] postNotificationName:NSSplitViewWillResizeSubviewsNotification object:splitView];
+
+ NSPoint clickLocation = [self convertPoint:[event locationInWindow] fromView:[self superview]];
+
+ NSRect newFrame = [[self superview] frame];
+ newFrame.size.width = clickLocation.x + _clickOffset;
+
+ id delegate = [splitView delegate];
+ if( delegate && [delegate respondsToSelector:@selector( splitView:constrainSplitPosition:ofSubviewAt: )] ) {
+ float new = [delegate splitView:splitView constrainSplitPosition:newFrame.size.width ofSubviewAt:0];
+ newFrame.size.width = new;
+ }
+
+ if( delegate && [delegate respondsToSelector:@selector( splitView:constrainMinCoordinate:ofSubviewAt: )] ) {
+ float min = [delegate splitView:splitView constrainMinCoordinate:0. ofSubviewAt:0];
+ newFrame.size.width = MAX( min, newFrame.size.width );
+ }
+
+ if( delegate && [delegate respondsToSelector:@selector( splitView:constrainMaxCoordinate:ofSubviewAt: )] ) {
+ float max = [delegate splitView:splitView constrainMaxCoordinate:0. ofSubviewAt:0];
+ newFrame.size.width = MIN( max, newFrame.size.width );
+ }
+
+ if( delegate ) {
+ [delegate setMinSize:NSMakeSize(newFrame.size.width + 551., 114.)];
+ }
+
+ [[self superview] setFrame:newFrame];
+
+ [splitView adjustSubviews];
+
+ [[NSNotificationCenter defaultCenter] postNotificationName:NSSplitViewDidResizeSubviewsNotification object:splitView];
+}
+@end