diff --git a/Cog.xcodeproj/project.pbxproj b/Cog.xcodeproj/project.pbxproj index 6f527c22a..87b6ca4c7 100644 --- a/Cog.xcodeproj/project.pbxproj +++ b/Cog.xcodeproj/project.pbxproj @@ -11,6 +11,8 @@ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; }; 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; + 8E1296DA0A2BA9CE00443124 /* PlaylistHeaderView.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E1296D80A2BA9CE00443124 /* PlaylistHeaderView.h */; }; + 8E1296DB0A2BA9CE00443124 /* PlaylistHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E1296D90A2BA9CE00443124 /* PlaylistHeaderView.m */; }; 8E4C7F090A0509FC003BE25F /* DragScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E4C7F070A0509FC003BE25F /* DragScrollView.m */; }; 8E6A8E2C0A0D8A68002ABE9C /* CoreAudioFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E6A8E280A0D8A68002ABE9C /* CoreAudioFile.m */; }; 8E6A8E380A0D8AD8002ABE9C /* CoreAudioUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E6A8E360A0D8AD8002ABE9C /* CoreAudioUtils.m */; }; @@ -131,6 +133,7 @@ 8E757B5509F326710080F1EE /* MAC.framework in CopyFiles */, 8E757B5609F326710080F1EE /* FLAC.framework in CopyFiles */, 8E757B5709F326710080F1EE /* OggFLAC.framework in CopyFiles */, + 8E1296DA0A2BA9CE00443124 /* PlaylistHeaderView.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -147,6 +150,8 @@ 32CA4F630368D1EE00C91783 /* Cog_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cog_Prefix.pch; sourceTree = ""; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; 8D1107320486CEB800E47090 /* Cog.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Cog.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8E1296D80A2BA9CE00443124 /* PlaylistHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PlaylistHeaderView.h; sourceTree = ""; }; + 8E1296D90A2BA9CE00443124 /* PlaylistHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PlaylistHeaderView.m; sourceTree = ""; }; 8E4C7F060A0509FC003BE25F /* DragScrollView.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DragScrollView.h; sourceTree = ""; }; 8E4C7F070A0509FC003BE25F /* DragScrollView.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = DragScrollView.m; sourceTree = ""; }; 8E643DF20A2B585600844A28 /* GameFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GameFile.h; sourceTree = ""; }; @@ -427,6 +432,8 @@ 8E75752A09F31D5A0080F1EE /* Playlist */ = { isa = PBXGroup; children = ( + 8E1296D80A2BA9CE00443124 /* PlaylistHeaderView.h */, + 8E1296D90A2BA9CE00443124 /* PlaylistHeaderView.m */, 8E75752B09F31D5A0080F1EE /* DNDArrayController.h */, 8E75752C09F31D5A0080F1EE /* DNDArrayController.m */, 8E75752D09F31D5A0080F1EE /* PlaylistController.h */, @@ -707,6 +714,7 @@ 8E6A8E2C0A0D8A68002ABE9C /* CoreAudioFile.m in Sources */, 8E6A8E380A0D8AD8002ABE9C /* CoreAudioUtils.m in Sources */, 8EEBC1B50A177D70006F6251 /* PlaylistEntry.xcdatamodel in Sources */, + 8E1296DB0A2BA9CE00443124 /* PlaylistHeaderView.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Playlist/PlaylistController.h b/Playlist/PlaylistController.h index e8928b98b..2e63eae15 100644 --- a/Playlist/PlaylistController.h +++ b/Playlist/PlaylistController.h @@ -77,4 +77,5 @@ - (IBAction)showFileInFinder:(id)sender; +- (void)handlePlaylistViewHeaderNotification:(NSNotification*)notif; @end diff --git a/Playlist/PlaylistController.m b/Playlist/PlaylistController.m index 0c798936b..a8ba93165 100644 --- a/Playlist/PlaylistController.m +++ b/Playlist/PlaylistController.m @@ -35,6 +35,9 @@ - (void)awakeFromNib { [super awakeFromNib]; + + NSNotificationCenter* ns = [NSNotificationCenter defaultCenter]; + [ns addObserver:self selector:@selector(handlePlaylistViewHeaderNotification:) name:@"PlaylistViewColumnSeparatorDoubleClick" object:nil]; } - (NSArray *)filesAtPath:(NSString *)path @@ -706,4 +709,60 @@ [ws selectFile:[curr filename] inFileViewerRootedAtPath:[curr filename]]; } +- (void)handlePlaylistViewHeaderNotification:(NSNotification*)notif +{ + NSTableView *tv = [notif object]; + NSNumber *colIdx = [[notif userInfo] objectForKey:@"column"]; + NSTableColumn *col = [[tv tableColumns] objectAtIndex:[colIdx intValue]]; + + // find which function to call on PlaylistEntry* + SEL sel; + NSString* identifier = [col identifier]; + BOOL isNumeric = NO; + if ([identifier compare:@"name"] == NSOrderedSame) + sel = @selector(title); + else if ([identifier compare:@"length"] == NSOrderedSame) + sel = @selector(lengthString); + else if ([identifier compare:@"index"] == NSOrderedSame) { + sel = @selector(index); + isNumeric = YES; + } + else if ([identifier compare:@"artist"] == NSOrderedSame) + sel = @selector(artist); + else if ([identifier compare:@"album"] == NSOrderedSame) + sel = @selector(album); + else if ([identifier compare:@"year"] == NSOrderedSame) + sel = @selector(year); + else if ([identifier compare:@"genre"] == NSOrderedSame) + sel = @selector(genre); + else if ([identifier compare:@"track"] == NSOrderedSame) { + sel = @selector(track); + isNumeric = YES; + } + else + return; + + NSCell *cell = [col dataCell]; + NSAttributedString * as = [cell attributedStringValue]; + + // find the longest string display length in that column + NSArray *entries = [self arrangedObjects]; + NSEnumerator *enumerator = [entries objectEnumerator]; + PlaylistEntry *entry; + float maxlength = -1; + NSString *ret; + while (entry = [enumerator nextObject]) { + if (isNumeric) + ret = [NSString stringWithFormat:@"%d", objc_msgSend(entry, sel)]; + else + ret = objc_msgSend(entry, sel); + if ([ret sizeWithAttributes:[as attributesAtIndex:0 effectiveRange:nil]].width > maxlength) + maxlength = [ret sizeWithAttributes:[as attributesAtIndex:0 effectiveRange:nil]].width; + } + + + // set the new width (plus a 5 pixel extra to avoid "..." string substitution) + [col setWidth:maxlength+5]; +} + @end diff --git a/Playlist/PlaylistHeaderView.h b/Playlist/PlaylistHeaderView.h new file mode 100644 index 000000000..317162e8a --- /dev/null +++ b/Playlist/PlaylistHeaderView.h @@ -0,0 +1,16 @@ +// +// PlaylistHeaderView.h +// Cog +// +// Created by Simon on 06-05-24. +// Copyright 2006 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface PlaylistHeaderView : NSTableHeaderView { + +} + +@end diff --git a/Playlist/PlaylistHeaderView.m b/Playlist/PlaylistHeaderView.m new file mode 100644 index 000000000..697113fc1 --- /dev/null +++ b/Playlist/PlaylistHeaderView.m @@ -0,0 +1,50 @@ +// +// PlaylistHeaderView.m +// Cog +// +// Created by Simon on 06-05-24. +// Copyright 2006 __MyCompanyName__. All rights reserved. +// + +#import "PlaylistHeaderView.h" + + +@implementation PlaylistHeaderView + +- (void)mouseDown:(NSEvent *)theEvent +{ + NSPoint event_location = [theEvent locationInWindow]; + NSPoint local_point = [self convertPoint:event_location fromView:nil]; + + int column = [self columnAtPoint:local_point]; + + if ([theEvent clickCount]==2 && column!=-1) { + + // compute whether the clickpoint is a column separator or not + BOOL clickedSeperator = NO; + // handle a click one pixel away at right + NSRect rect = [self headerRectOfColumn:column]; + if (abs(rect.origin.x - local_point.x) <= 1 && column > 0) { + --column; + clickedSeperator = YES; + } + // handle a click 3 pixels away at left + else if (abs(rect.origin.x + rect.size.width - local_point.x) <= 3) + clickedSeperator = YES; + + if (clickedSeperator) { + + NSNotificationCenter *center; + center = [NSNotificationCenter defaultCenter]; + [center postNotificationName: @"PlaylistViewColumnSeparatorDoubleClick" object: + [self tableView] userInfo: + [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:column],@"column", nil]]; + } + else + [super mouseDown: theEvent]; + } + else + [super mouseDown: theEvent]; +} + +@end diff --git a/Playlist/PlaylistView.m b/Playlist/PlaylistView.m index 1bfa6cc2c..390eb6bd2 100644 --- a/Playlist/PlaylistView.m +++ b/Playlist/PlaylistView.m @@ -10,6 +10,8 @@ #import "PlaybackController.h" #import "PlaylistController.h" +#import "PlaylistHeaderView.h" + @implementation PlaylistView - (void)awakeFromNib @@ -28,6 +30,15 @@ [[c dataCell] setFont:f]; } + NSTableHeaderView *currentTableHeaderView = [self headerView]; + PlaylistHeaderView *customTableHeaderView = [[PlaylistHeaderView alloc] init]; + + [customTableHeaderView setFrame:[currentTableHeaderView frame]]; + [customTableHeaderView setBounds:[currentTableHeaderView bounds]]; +// [self setColumnAutoresizingStyle:NSTableViewNoColumnAutoresizing]; + + [self setHeaderView:customTableHeaderView]; + [self setVerticalMotionCanBeginDrag:YES]; } @@ -73,7 +84,7 @@ BOOL currentRowIsSelected = [[self selectedRowIndexes] containsIndex:row]; if (!currentRowIsSelected) [self selectRow:row byExtendingSelection:NO]; - + if ([self numberOfSelectedRows] <=0) { //No rows are selected, so the table should be displayed with all items disabled