For learning purposes i would like to convert a cell-based NSOutlineView to a view-based one,
basically i would like the following:
NSTreeController
Here is the 'worlds simplest NSOutlineView' example http://www.cocoasteam.com/Cocoa_Steam/Worlds_Simplest_Demo.html
I wonder if someone could modify it to make it view-based and work like i said above :) :)
I've tried looking at apple examples, and searching elsewhere on the internet but i still can't get it to work - so thanks very much in advance :)
I have created a little sample project which does just that.
Check out besi/mac-quickies on github. Most of the stuff is either done in IB or can be found in the AppDelegate
OK, so you want an NSOutlineView
with ImageAndTextCell
cells, right?
Let's do one of the most typical examples of this kind : a simple file explorer.
What we'll need :
NSOutlineView
(put an outline to your AppDelegate, as fileOutlineView
)NameColumn
, SizeColumn
, ModifiedColumn
Now, as for the rest, I'll do it all programmatically, so that you get a good idea of what's going on...
How to set it up (e.g. in - (void)awakeFromNib
):
// set the Data Source and Delegate
[fileOutlineView setDataSource:(id<NSOutlineViewDataSource>)self];
[fileOutlineView setDelegate:(id<NSOutlineViewDelegate>)self];
// set the first column's cells as `ImageAndTextCell`s
ImageAndTextCell* iatc = [[ImageAndTextCell alloc] init];
[iatc setEditable:NO];
[[[fileOutlineView tableColumns] objectAtIndex:0] setDataCell:iatc];
Connecting the dots :
/*******************************************************
*
* OUTLINE-VIEW DATASOURCE
*
*******************************************************/
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
{
if ([item isFolder])
return YES;
else
return NO;
}
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
{
if (item==nil)
{
// Root
return [[filePath folderContentsWithPathAndBackIgnoringHidden] count];
}
else
{
if ([item isFolder])
{
return [[item folderContentsWithPathAndBackIgnoringHidden] count];
}
else
{
return 0;
}
}
}
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
{
if (item == nil)
{
// Root
return [[filePath folderContentsWithPathAndBackIgnoringHidden] objectAtIndex:index];
}
if ([item isFolder])
{
return [[item folderContentsWithPathAndBackIgnoringHidden] objectAtIndex:index];
}
// File
return nil;
}
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)theColumn byItem:(id)item
{
if ([[theColumn identifier] isEqualToString:@"NameColumn"])
{
return [item lastPathComponent];
}
else if ([[theColumn identifier] isEqualToString:@"SizeColumn"])
{
if ([item isFolder]) return @"--";
else return [NSString stringWithFormat:@"%d",[item getFileSize]];
}
else if ([[theColumn identifier] isEqualToString:@"ModifiedColumn"])
{
if ([item isFolder]) return @"";
else return [NSString stringWithFormat:@"%@",[item getDateModified]];
}
// Never reaches here
return nil;
}
/*******************************************************
*
* OUTLINE-VIEW DELEGATE
*
*******************************************************/
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
{
return YES;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item
{
return NO;
}
- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
[cell setDrawsBackground:NO];
if ([item isFileHidden]) [cell setTextColor:[NSColor grayColor]];
else [cell setTextColor:[NSColor whiteColor]];
if ([[tableColumn identifier] isEqualToString:@"NameColumn"])
{
if ([item isFolder])
[cell setImage:[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericFolderIcon)] size:15.0];
else
[cell setImage:[[NSWorkspace sharedWorkspace] iconForFile:item] size:15.0];
if ([item isFileHidden])
{
[cell setFileHidden:YES];
}
else
{
[cell setFileHidden:NO];
}
}
}
Hint : ImageAndTextCell
class can be found here. You'll also notice a few other methods I'm using, which are obviously NOT supported by Cocoa (e.g. isFileHidden
, isFolder
or folderContentsWithPathAndBackIgnoringHidden
) but it's not that difficult to implement them yourself...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With