Navigation Menu

Skip to content

Commit

Permalink
Move icon cache to a class and release all icons when a window closes.
Browse files Browse the repository at this point in the history
  • Loading branch information
alloy committed Oct 2, 2012
1 parent 04d0e0d commit 102d675
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 51 deletions.
1 change: 0 additions & 1 deletion src/MacVim/MMFileBrowser/MMFileBrowserController.m
Expand Up @@ -147,7 +147,6 @@ - (void)setRoot:(NSString *)root
rootItem = [[MMFileBrowserFSItem alloc] initWithPath:root
vim:[windowController vimController]];
[rootItem loadChildrenRecursive:NO expandedChildrenOnly:YES];
NSLog(@"ROOT ITEM: %@", rootItem);
[fileBrowser reloadData];
[fileBrowser expandItem:rootItem];
[pathControl setURL:[NSURL fileURLWithPath:root]];
Expand Down
11 changes: 2 additions & 9 deletions src/MacVim/MMFileBrowser/MMFileBrowserFSItem.h
Expand Up @@ -2,17 +2,10 @@

@class MMVimController;

@interface MMFileBrowserFSItem : NSObject {
char *cpath;
BOOL isDir;
MMFileBrowserFSItem *parent;
MMVimController *vim;
BOOL includesHiddenFiles;
BOOL ignoreNextReload;
NSImage *icon;
}
@interface MMFileBrowserFSItem : NSObject

@property (nonatomic, assign) BOOL includesHiddenFiles, ignoreNextReload;
@property (readonly) BOOL isDir;
@property (readonly) MMFileBrowserFSItem *parent;
@property (nonatomic, retain) NSMutableArray *children;

Expand Down
131 changes: 90 additions & 41 deletions src/MacVim/MMFileBrowser/MMFileBrowserFSItem.m
Expand Up @@ -2,19 +2,31 @@
#import "MMVimController.h"
#include <fts.h>


@interface MMFileBrowserFSItem ()
@class MMFileBrowserFSItemIconCache;

@interface MMFileBrowserFSItem () {
char *cpath;
MMFileBrowserFSItem *parent;
MMVimController *vim;
BOOL includesHiddenFiles;
BOOL ignoreNextReload;
NSImage *icon;
MMFileBrowserFSItemIconCache *iconCache;
}

@property (readonly) const char *cpath;

- (id)initWithPath:(char *)thePath
parent:(MMFileBrowserFSItem *)parentItem
isDir:(BOOL)dir
iconCache:(MMFileBrowserFSItemIconCache *)theIconCache
vim:(MMVimController *)vimInstance;
- (MMFileBrowserFSItem *)_itemAtPath:(NSArray *)components;

@end



@interface MMFileBrowserFSItemStack : NSObject

@property (readonly) NSMutableArray *stack;
Expand Down Expand Up @@ -129,34 +141,97 @@ - (MMFileBrowserFSItem *)existingChild:(const char *)filename;
@end


@implementation MMFileBrowserFSItem
@interface MMFileBrowserFSItemIconCache : NSObject {
NSMutableDictionary *cache;
}
@end

@implementation MMFileBrowserFSItemIconCache

- (void)dealloc;
{
[cache release];
[super dealloc];
}

- (id)init;
{
if ((self = [super init])) {
cache = [NSMutableDictionary new];
}
return self;
}

- (NSImage *)iconForItem:(MMFileBrowserFSItem *)item;
{
NSString *type = nil;
NSString *path = nil;
if (item.isDir) {
type = [[item relativePath] pathExtension];
if (type.length > 0) {
// This is possibly a 'bundle' dir (e.g. Foo.xcodeproj).
path = [item fullPath];
} else {
// It's not a 'bundle' dir, so use a normal folder icon.
type = @"MMFileBrowserFolder";
path = @"/var"; // Just pick a dir that's guaranteed to have a normal folder icon.
}
} else {
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
if (![ws getInfoForFile:[item fullPath] application:NULL type:&type]) {
NSLog(@"FAILED TO FIND INFO FOR %@", [item fullPath]);
type = @"";
}
}
return [self iconForFileType:type isDir:item.isDir path:path];
}

// TODO remove this from the global namespace, have one instance shared by all fs items for one file browser instance
static NSMutableDictionary *iconCache = nil;
+ (void)initialize {
if (self == [MMFileBrowserFSItem class]) {
iconCache = [NSMutableDictionary new];
- (NSImage *)iconForFileType:(NSString *)type isDir:(BOOL)isDir path:(NSString *)path;
{
NSImage *icon = [cache valueForKey:type];
if (icon == nil) {
if (isDir) {
icon = [[NSWorkspace sharedWorkspace] iconForFile:path];
} else {
icon = [[NSWorkspace sharedWorkspace] iconForFileType:type];
}
[icon setSize:NSMakeSize(16, 16)];
[cache setValue:icon forKey:type];
}
return icon;
}

@synthesize parent, cpath, includesHiddenFiles, ignoreNextReload, children;
@end



@implementation MMFileBrowserFSItem

@synthesize parent, isDir, cpath, includesHiddenFiles, ignoreNextReload, children;

- (void)dealloc {
[children release];
free(cpath);
[icon release];
if (!parent) {
[iconCache release];
}
vim = nil;
[super dealloc];
}

- (id)initWithPath:(NSString *)thePath vim:(MMVimController *)vimInstance;
{
return [self initWithPath:(char *)[thePath UTF8String] parent:nil isDir:YES vim:vimInstance];
return [self initWithPath:(char *)[thePath UTF8String]
parent:nil
isDir:YES
iconCache:nil
vim:vimInstance];
}

- (id)initWithPath:(char *)thePath
parent:(MMFileBrowserFSItem *)parentItem
isDir:(BOOL)dir
iconCache:(MMFileBrowserFSItemIconCache *)theIconCache
vim:(MMVimController *)vimInstance;
{
if ((self = [super init])) {
Expand All @@ -169,8 +244,10 @@ - (id)initWithPath:(char *)thePath

if (parent) {
includesHiddenFiles = parent.includesHiddenFiles;
iconCache = theIconCache;
} else {
includesHiddenFiles = NO;
iconCache = [MMFileBrowserFSItemIconCache new];
}
ignoreNextReload = NO;
}
Expand Down Expand Up @@ -286,6 +363,7 @@ - (BOOL)loadChildrenRecursive:(BOOL)recursive expandedChildrenOnly:(BOOL)expande
child = [[MMFileBrowserFSItem alloc] initWithPath:node->fts_name
parent:stack.currentItem
isDir:dir
iconCache:iconCache
vim:vim];
[stack.currentChildren addObject:child];
[child release];
Expand Down Expand Up @@ -344,36 +422,7 @@ - (NSInteger)numberOfChildren {
// TODO for now we don't really resize
- (NSImage *)icon {
if (icon == nil) {
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
NSString *type;
NSString *path = nil;
if (isDir) {
type = [[self relativePath] pathExtension];
if (type.length > 0) {
// This is possibly a 'bundle' dir (e.g. Foo.xcodeproj).
path = [self fullPath];
} else {
// It's not a 'bundle' dir, so use a normal folder icon.
type = @"MMFileBrowserFolder";
path = @"/var"; // Just pick a dir that's guaranteed to have a normal folder icon.
}
} else {
if (![ws getInfoForFile:[self fullPath] application:NULL type:&type]) {
NSLog(@"FAILED TO FIND INFO FOR %@", [self fullPath]);
type = @"";
}
}
icon = [iconCache valueForKey:type];
if (icon == nil) {
if (isDir) {
icon = [ws iconForFile:path];
} else {
icon = [ws iconForFileType:type];
}
[icon setSize:NSMakeSize(16, 16)];
[iconCache setValue:icon forKey:type];
}
[icon retain];
icon = [iconCache iconForItem:self];
}
return icon;
}
Expand Down

0 comments on commit 102d675

Please sign in to comment.