在MAC应用里显示多个图片(IKImageBrowserView控件使用)

在MAC应用里显示多个图片(IKImageBrowserView控件使用)


在MAC应用里显示多个图片

本文参考的是:ImageViewer.v1.0.zip 从网络下载,并且做了少量整理。

原理:


1.使用的技术是:IKImageBrowserView 这个控件,可以在Object library里面找到


2.然后写一个继承类,就可以使用了。

步骤:从Object  Library里面找到IKImageBrowserView这个控件

然后,拖动倒窗口中,也可以放在视图里面


3.然后开始给这个控件绑定数据源DataSource和数据委托类Delegate


4.然后给控件设置变量


5.然后给控件设置图片所在文件夹路径,这样就可以显示文件夹里面的所有图片了。


代码如下:

1。需要一个工具包 Utils文件夹里面的所有类,没有修改

2。需要ImageBrowserView这个文件夹里面的所有文件

      并且做了少量修改。

      主要是针对标题,当得到图片后,再后期修改。

==========

// FileUtils.h


#import <Cocoa/Cocoa.h>



/**

This class is responsible for interacting with the filesystem. It's meant

to be instanciated through a XIB file (I use awakFromNib to initialize it)

*/

@interface FileUtils

: NSObject

{


@private


NSMutableArray *mCutItems;

NSMutableArray *mCopiedItems;

NSString *mDestinationDirectory;


}


@property (copy)NSString * destinationDirectory;


// init / deinit

-(void)awakeFromNib;

-(void)dealloc;


// global accessor

+(FileUtils *)instance;


// misc

+(BOOL)isImage:(NSString *)path;

+(BOOL)isGIF:(NSString *)path;


// delete / copy-cut / paste support

-(void)removeItemAtPath:(NSString *)path;

-(void)copyItems:(NSArray *)items;

-(void)cutItems:(NSArray *)items;

-(void)paste;

-(void)pasteTo:(NSString *)destination;

-(BOOL)canPaste;

-(void)setCanPaste:(BOOL)canPaste;


@end

========

// FileUtils.m



#import "FileUtils.h"

#import "Utils.h"

#import "SimpleProfiler.h"

//#import "../Preferences/Preferences.h"



@implementation FileUtils



static FileUtils * instance =nil;


@synthesize destinationDirectory = mDestinationDirectory;



-(void)awakeFromNib

{

instance= self;

mDestinationDirectory= nil;

mCutItems= [[NSMutableArray alloc] init];

mCopiedItems= [[NSMutableArray alloc]init];

}


-(void)dealloc

{

instance =nil;

[mCutItemsrelease];

[mCopiedItemsrelease];

[mDestinationDirectoryrelease];

[superdealloc];

}


+(FileUtils *)instance

{

returninstance;

}


+(BOOL)isImage:(NSString *)path

{

PROFILING_START(@"FileUtils - isImage");


NSString * extension = [[pathpathExtension] lowercaseString];

if ([extensionisEqualToString:@"jpg"] ==YES ||

[extension isEqualToString:@"jpeg"] ==YES ||

[extension isEqualToString:@"gif"] ==YES ||

[extension isEqualToString:@"png"] ==YES ||

[extension isEqualToString:@"psd"] ==YES ||

[extension isEqualToString:@"tiff"] ==YES ||

[extension isEqualToString:@"tif"] ==YES ||

[extension isEqualToString:@"dng"] ==YES ||

[extension isEqualToString:@"cr2"] ==YES ||

[extension isEqualToString:@"raw"] ==YES ||

[extension isEqualToString:@"pdf"] ==YES)

{

PROFILING_STOP();

returnYES;

}


PROFILING_STOP();

returnNO;

}


+(BOOL)isGIF:(NSString *)path

{

NSString * extension = [[pathpathExtension] lowercaseString];

return [extensionisEqualToString:@"gif"];

}


-(void)removeItemAtPath:(NSString *)path

{

// check the preferences to see if we need to use the recycled bin, or

// permanently delete files

    BOOL permanently = YES;

    //[[Preferences instance] boolForKey:@"permanentlyDeleteFiles"];

if (permanently ==YES)

{

NSFileManager * fileManager = [NSFileManagerdefaultManager];

[fileManager removeItemAtPath:patherror:NULL];

}

else

{

NSInteger tag =0;

NSString * source = [pathstringByDeletingLastPathComponent];

NSArray * files = [NSArrayarrayWithObject:[path lastPathComponent]];

NSWorkspace * workspace = [NSWorkspacesharedWorkspace];

[workspace performFileOperation:NSWorkspaceRecycleOperation

  source:source

  destination:nil

  files:files

  tag:&tag];

}

}


/**

Private method used to clear previously copied/cut items.

*/

-(void)clear

{

[mCopiedItemsremoveAllObjects];

[mCutItemsremoveAllObjects];

}


-(void)copyItems:(NSArray *)items

{

[self clear];

[mCopiedItemsaddObjectsFromArray:items];

[selfsetCanPaste:YES];

}


-(void)cutItems:(NSArray *)items

{

[self clear];

[mCutItemsaddObjectsFromArray:items];

[selfsetCanPaste:YES];

}


-(BOOL)canPaste

{

if ([mCutItemscount] > 0 || [mCopiedItemscount] > 0)

returnYES;

returnNO;

}


-(void)setCanPaste:(BOOL)canPaste

{

// this is just used for binding : when an item is added to the copy or

// cut list, we call [self setCanPaste:whatever] to notify binded objects.

}


-(void)paste

{

if (mDestinationDirectory !=nil)

[selfpasteTo:mDestinationDirectory];

}


-(void)pasteTo:(NSString *)destination

{

NSFileManager * fileManager = [NSFileManagerdefaultManager];


// handle cut files

for (NSURL * urlin mCutItems)

{

// check if the destination folder is different from the source folder

if ([destinationisEqualToString:[[url path]stringByDeletingLastPathComponent]])

continue;

NSURL * destinationURL = [NSURLfileURLWithPath:destination];

destinationURL = [destinationURL URLByAppendingPathComponent:[url lastPathComponent]];

// little hack : if the destination already exists, moving wont work,

// so I remove the destination before moving. This might be a bit

// "unsafe", but I don't want to bloat the code for something that will

// happen with a 0.000001% chance.

[fileManager removeItemAtURL:destinationURLerror:nil];

[fileManager moveItemAtURL:urltoURL:destinationURL error:nil];

}


// handle copied files

for (NSURL * urlin mCopiedItems)

{

// check if the destination folder is different from the source folder

if ([destinationisEqualToString:[[url path]stringByDeletingLastPathComponent]])

continue;


NSURL * destinationURL = [NSURLfileURLWithPath:destination];

destinationURL = [destinationURL URLByAppendingPathComponent:[url lastPathComponent]];

[fileManager copyItemAtURL:urltoURL:destinationURL error:nil];

}


[self clear];

}


@end

====

// FSEventsListener.h


#import <Foundation/Foundation.h>



/**

This defines a little protocol which should be implemented by objects that

want to be notified of file changes (objects set as delegate of the

FSEventsListener class)

*/

@protocol FSEventListenerDelegate< NSObject >


@required


-(void)fileWasAdded:(NSString *)file;

-(void)fileWasRemoved:(NSString *)file;

-(void)fileWasRenamed:(NSString *)oldFile to:(NSString *)newFile;


-(void)directoryWasAdded:(NSString *)directory;

-(void)directoryWasRemoved:(NSString *)directory;

-(void)directoryWasRenamed:(NSString *)oldDirectory to:(NSString *)newDirectory;


@end



/**

This class is a little helper to create file system events listeners. It

allow to schedule event watching on a particular directory, and specify a

delegate which will be called on each supported event.

*/

@interface FSEventsListener

: NSObject

{


@private


NSDictionary *mListeners;

FSEventStreamRefmFileStream;


}


@property (assign)NSDictionary *listeners;


-(id)init;

-(void)dealloc;


// singleton handling

+(FSEventsListener *)instance;

+(void)destroy;


// handle listeners

-(void)addListener:(NSObject<FSEventListenerDelegate > *)listener forPath:(NSString *)path;

-(void)removeListener:(NSObject<FSEventListenerDelegate > *)listener forPath:(NSString *)path;


// utils

-(NSString *)formatPath:(NSString *)path;


// used to dispatch events to listeners

-(void)fileWasAdded:(NSString *)file;

-(void)fileWasRemoved:(NSString *)file;

-(void)fileWasRenamed:(NSString *)oldFile to:(NSString *)newFile;

-(void)directoryWasAdded:(NSString *)directory;

-(void)directoryWasRemoved:(NSString *)directory;

-(void)directoryWasRenamed:(NSString *)oldDirectory to:(NSString *)newDirectory;


@end


====

// FSEventsListener.m



#import "FSEventsListener.h"

#import "Utils.h"

#import "FileUtils.h"



void fsevents_callback(ConstFSEventStreamRef streamRef,

                       void * userData,

                       size_t numEvents,

                       void * eventPaths,

                       const FSEventStreamEventFlags eventFlags[],

                       const FSEventStreamEventId eventIds[]);


@implementation FSEventsListener


static FSEventsListener * instance =nil;


@synthesize listeners= mListeners;



-(id)init

{

self = [superinit];

if (self ==nil)

returnnil;


mListeners = [[NSMutableDictionaryalloc] init];


// create the context that will be associated to the stream. We pass a

// pointer to the FSEventsListener instance as user data.

FSEventStreamContext context = {0, (void *)self,NULL, NULL,NULL };


// create the event stream, with a flag telling that we want to watch file

// level events. This will allow to directly retrieve the file names in the

// callback, instead of just the name of the directory

mFileStream =FSEventStreamCreate(NULL,

  &fsevents_callback,

  &context,

  (CFArrayRef)[NSArrayarrayWithObject:@"/"],

  kFSEventStreamEventIdSinceNow,

  (CFAbsoluteTime)0.2,

  kFSEventStreamCreateFlagFileEvents);


// start the stream on the main event loop

FSEventStreamScheduleWithRunLoop(mFileStream,

CFRunLoopGetCurrent(),

kCFRunLoopDefaultMode);

FSEventStreamStart(mFileStream);


// init the globally accessible instance

instance =self;


returnself;

}


-(void)dealloc

{

// clear the instance

instance =nil;


// stop and clean event stream

FSEventStreamStop(mFileStream);

FSEventStreamUnscheduleFromRunLoop(mFileStream

  CFRunLoopGetCurrent(),

  kCFRunLoopDefaultMode);

FSEventStreamInvalidate(mFileStream);

FSEventStreamRelease(mFileStream);


[mListenersrelease];

[superdealloc];

}


+(FSEventsListener *)instance

{

if (instance ==nil)

{

[[FSEventsListeneralloc] init];

}

returninstance;

}


+(void)destroy

{

if (instance !=nil)

{

[instancerelease];

instance =nil;

}

}


/**

ensure pathes are always formated the same way : except for the root '/'

path, every path must NOT end with a trailing '/'

*/

-(NSString *)formatPath:(NSString *)path

{

if ([pathcharacterAtIndex:[path length] - 1] == '/')

{

return [pathsubstringToIndex:[path length] - 1]; 

}

return [[pathcopy] autorelease];

}


-(void)addListener:(NSObject<FSEventListenerDelegate > *)listener forPath:(NSString *)path

{

NSString * formatedPath = [selfformatPath:path]; 

NSMutableArray * listeners = [mListenersobjectForKey:formatedPath];

if (listeners ==nil)

{

[mListenerssetValue:[NSMutableArrayarrayWithObject:listener] forKey:formatedPath];

}

else

{

[listeners addObject:listener];

}

}


-(void)removeListener:(NSObject<FSEventListenerDelegate > *)listener forPath:(NSString *)path

{

NSString * formatedPath = [selfformatPath:path]; 

NSMutableArray * listeners = [mListenersobjectForKey:formatedPath];

if (listeners !=nil)

{

[listeners removeObject:listener];

}

}


-(void)fileWasAdded:(NSString *)file

{

NSString * path = [filestringByDeletingLastPathComponent];

NSArray * listeners = [mListenersobjectForKey:path];

for (NSObject<FSEventListenerDelegate > * listener in listeners)

[listener fileWasAdded:file];

}


-(void)fileWasRemoved:(NSString *)file

{

NSString * path = [filestringByDeletingLastPathComponent];

NSArray * listeners = [mListenersobjectForKey:path];

for (NSObject<FSEventListenerDelegate > * listener in listeners)

[listener fileWasRemoved:file];

}


-(void)fileWasRenamed:(NSString *)oldFile to:(NSString *)newFile

{

NSString * path = [newFilestringByDeletingLastPathComponent];

NSArray * listeners = [mListenersobjectForKey:path];

for (NSObject<FSEventListenerDelegate > * listener in listeners)

[listener fileWasRenamed:oldFileto:newFile];

}


-(void)directoryWasAdded:(NSString *)directory

{

NSString * path = [directorystringByDeletingLastPathComponent];

NSArray * listeners = [mListenersobjectForKey:path];

for (NSObject<FSEventListenerDelegate > * listener in listeners)

[listener directoryWasAdded:directory];

}


-(void)directoryWasRemoved:(NSString *)directory

{

NSString * path = [directorystringByDeletingLastPathComponent];

NSArray * listeners = [mListenersobjectForKey:path];

for (NSObject<FSEventListenerDelegate > * listener in listeners)

[listener directoryWasRemoved:directory];

}


-(void)directoryWasRenamed:(NSString *)oldDirectory to:(NSString *)newDirectory

{

NSString * path = [newDirectorystringByDeletingLastPathComponent];

NSArray * listeners = [mListenersobjectForKey:path];

for (NSObject<FSEventListenerDelegate > * listener in listeners)

[listener directoryWasRenamed:oldDirectoryto:newDirectory];

}


@end



#define CHECK_STREAM(x, y) if (((x) & (y)) == (y)) NSLog(@"    %s", #y);


void fsevents_callback(ConstFSEventStreamRef streamRef,

                       void * userData,

                       size_t numEvents,

                       void * eventPaths,

                       const FSEventStreamEventFlags eventFlags[],

                       const FSEventStreamEventId eventIds[])

{

static NSString * previousRenamedPath = nil;

FSEventsListener * eventListener = (FSEventsListener *)userData;

size_ti;

char ** paths= eventPaths;

for (i = 0; i < numEvents; ++i)

{

NSString * newName = [NSStringstringWithFormat:@"%s", paths[i]];


// first, we handle events WITHOUT the renamed flag. Those are simple

// event, like "created", "removed". Note that when a device is mounted,

// or unmounted, a corresponding "created" or "removed" event is

// triggered, so we don't need to handle mount/unmount event.


if ((eventFlags[i] &kFSEventStreamEventFlagItemRenamed) == 0)

{

if (eventFlags[i] &kFSEventStreamEventFlagItemRemoved)

{

// a file or directory was permanently deleted

//if (eventFlags[i] & kFSEventStreamEventFlagItemIsFile)

                if (eventFlags[i])

{

[eventListener fileWasRemoved:newName];

}

elseif (eventFlags[i] &kFSEventStreamEventFlagItemIsDir)

{

[eventListener directoryWasRemoved:newName];

}

}

elseif (eventFlags[i] &kFSEventStreamEventFlagItemCreated)

{

// a file or directory was copied/created

//if (eventFlags[i] & kFSEventStreamEventFlagItemIsFile)

                if (eventFlags[i])

{

[eventListener fileWasAdded:newName];

}

elseif (eventFlags[i] &kFSEventStreamEventFlagItemIsDir)

{

[eventListener directoryWasAdded:newName];

}

}

}

else

{


// here, the "renamed" flag is present. From what I can guess

// through experiments, when a file is renamed, or moved, or sent

// to the trash, it triggers 2 successive renamed events. The first

// contains the source file, the second the destination file.

// So I just use a static string to store the first event path and

// detect if it's the first or second event.


if (previousRenamedPath ==nil)

{

previousRenamedPath = [newName retain];

}

else

{

NSString * newDir = [newNamestringByDeletingLastPathComponent];

NSString * oldName = previousRenamedPath;

NSString * oldDir = [oldNamestringByDeletingLastPathComponent];

//if (eventFlags[i] & kFSEventStreamEventFlagItemIsFile)

                if (eventFlags[i])

{

if ([oldDirisEqualToString:newDir])

{

// both directory are the same : file renamed

[eventListener fileWasRenamed:oldNameto:newName];

}

else

{

// directories are different, the file was moved

[eventListener fileWasAdded:newName];

[eventListener fileWasRemoved:oldName];

}

}

elseif (eventFlags[i] &kFSEventStreamEventFlagItemIsDir)

{

if ([oldDirisEqualToString:newDir])

{

// both directory are the same : renamed

[eventListener directoryWasRenamed:oldNameto:newName];

}

else

{

// directories are different, the directory was moved

[eventListener directoryWasAdded:newName];

[eventListener directoryWasRemoved:oldName];

}

}


// reset the previous renamed path.

SAFE_RELEASE(previousRenamedPath);

}

}

#if defined(DEBUG)

// NSLog(@"event [%d] [%d] [%s]", (int)eventIds[i], eventFlags[i], paths[i]);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagNone);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagMustScanSubDirs);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagUserDropped);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagKernelDropped);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagEventIdsWrapped);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagHistoryDone);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagRootChanged);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagMount);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagUnmount);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemCreated);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemRemoved);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemInodeMetaMod);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemRenamed);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemModified);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemFinderInfoMod);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemChangeOwner);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemXattrMod);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemIsFile);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemIsDir);

// CHECK_STREAM(eventFlags[i], kFSEventStreamEventFlagItemIsSymlink);

#endif // _DEBUG

}

}

======

// SimpleProfiler.h



#import <Cocoa/Cocoa.h>



@class ProfilingEntry;



@interface SimpleProfiler

: NSObject

{


@private


NSMutableDictionary *mEntries;


}


+(SimpleProfiler *)instance;

+(void)destroyInstance;


-(id)init;

-(void)dealloc;

-(void)addEntry:(NSString *)name withTime:(double)time;

-(void)log;


@end



@interface ProfilingEntry

: NSObject

{


@private


NSString *mName;

NSMutableArray *mTimes;

}


@property (copy) NSString * name;


+(ProfilingEntry *)entryWithName:(NSString *)name;


-(id)init;

-(void)dealloc;

-(double)averageTime;

-(void)addTime:(double)time;


@end


#if defined(PROFILING)

# define PROFILING_START(name) \

NSString * __name = name; \

NSDate * __date = [NSDate date]

#else

# define PROFILING_START(name)

#endif


#if defined(PROFILING)

# define PROFILING_STOP() \

[[SimpleProfiler instance] addEntry:__name \

  withTime:[[NSDate date] timeIntervalSinceDate:__date]]

#else

# define PROFILING_STOP()

#endif

======

// SimpleProfiler.m




#import "SimpleProfiler.h"


static SimpleProfiler * mSimpleProfilerInstance =nil;


@implementation SimpleProfiler


+(SimpleProfiler *)instance

{

if (mSimpleProfilerInstance ==nil)

mSimpleProfilerInstance = [[SimpleProfileralloc] init];

returnmSimpleProfilerInstance;

}


+(void)destroyInstance

{

if (mSimpleProfilerInstance !=nil)

{

[mSimpleProfilerInstancerelease];

mSimpleProfilerInstance =nil;

}

}


-(id)init

{

self = [superinit];

if (self)

{

mEntries = [[NSMutableDictionaryalloc] init];

}

returnself;

}


-(void)dealloc

{

[mEntriesremoveAllObjects];

[mEntriesrelease];

[superdealloc];

}


-(void)addEntry:(NSString *)name withTime:(double)time

{

ProfilingEntry * entry =nil;

entry = [mEntriesobjectForKey:name];

if (entry ==nil)

{

entry = [ProfilingEntryentryWithName:name];

[mEntriessetValue:entry forKey:name];

}

[entry addTime:time];

}


-(void)log

{

if ([mEntriescount] == 0)

return;


NSLog(@"Profiling log");

for (ProfilingEntry * entryin [mEntriesallValues])

{

NSLog(@"%@ -- %f", [entryname], [entry averageTime]);

}

}


@end


@implementation ProfilingEntry


@synthesize name = mName;


+(ProfilingEntry *)entryWithName:(NSString *)name

{

ProfilingEntry * entry = [[[ProfilingEntryalloc] init] autorelease];

[entry setName:name];

return entry;

}


-(id)init

{

self = [superinit];

if (self)

{

mName = nil;

mTimes = [[NSMutableArrayalloc] init];

}

returnself;

}


-(void)dealloc

{

[mNamerelease];

[mTimesrelease];

[superdealloc];

}


-(double)averageTime

{

double averageTime =0.0;

for (NSNumber * numberin mTimes)

{

averageTime += [number doubleValue];

}

return averageTime / (double)[mTimescount];

}


-(void)addTime:(double)time

{

[mTimesaddObject:[NSNumbernumberWithDouble:time]];

}


@end

====

//SlideShow.h


#import <Foundation/Foundation.h>


@interface SlideShow

: NSObject

{

}


+(void)startSlideShow:(NSObject *)target callback:(NSString *)callback;

+(void)stopSlideShow;

+(BOOL)isRunning;


@end

=====

// SlideShow.m

#import "SlideShow.h"

#import "Utils.h"



@implementation SlideShow



static NSTimer * slideshowTimer =nil;



+(void)startSlideShow:(NSObject *)target callback:(NSString *)callback

{

if (slideshowTimer !=nil)

[SlideShowstopSlideShow];


// get the slideshow user preferences

NSUserDefaultsController * defaults = [NSUserDefaultsControllersharedUserDefaultsController];

BOOL loop = [[[defaultsvalues] valueForKey:@"slideshowLoop"]boolValue];

float interval = [[[defaultsvalues] valueForKey:@"slideshowInterval"]floatValue];

// launch the slideshow. I use a simple NSTimer with scheduledTimerWithTimeInterval.

// This method creates the timer and automatically fire it after "interval" secondes.

slideshowTimer = [NSTimerscheduledTimerWithTimeInterval:interval

  target:target

  selector:NSSelectorFromString(callback)

  userInfo:loop ?@"Y" : @"N"

  repeats:YES];

[slideshowTimersetFireDate:[NSDatedateWithTimeIntervalSinceNow:interval]];

}


+(void)stopSlideShow

{

if (slideshowTimer !=nil)

{

[slideshowTimerinvalidate];

[slideshowTimerrelease];

slideshowTimer =nil;

}

}


+(BOOL)isRunning

{

returnslideshowTimer == nil ?NO : YES;

}



@end

=====


//Utils.h


#import <AppKit/AppKit.h>



@interface Utils

: NSObject

{

}


+(void)bind:(id)src

  keyPath:(NSString *)srcKey

  to:(id)dest

  keyPath:(id)destKey

  continuous:(BOOL)continuous

  twoWay:(BOOL)twoWay;

+(NSMutableParagraphStyle *)defaultParagraphStyle;

+(NSSize)stringSize:(NSString *)string withAttribute:(NSDictionary *)attributes;


@end



// Use this macro to output debug infos and strip them in release

#if defined(DEBUG)

# define DEBUG_LOG(...) NSLog(__VA_ARGS__)

#else

# define DEBUG_LOG(...)

#endif


// Use this macro to do something only in debug

#if defined(DEBUG)

# define DEBUG_ONLY(args) args

#else

# define DEBUG_ONLY(args)

#endif


// This macro is used when launching the ImageViewer from outside XCode :

// since we don't have access to the log, we need a way to debug

#if defined(DEBUG)

# define DEBUG_ALERT(...) \

{ \

NSAlert * __alert = [[[NSAlert alloc] init] autorelease]; \

[__alert setMessageText:[NSString stringWithFormat:__VA_ARGS__]]; \

[__alert runModal]; \

}

#else

# define DEBUG_ALERT(...)

#endif


// this macro is used to release an object and re-assign its value to nil, only

// if it's different from nil.

#if !defined(SAFE_RELEASE)

# define SAFE_RELEASE(x) if ((x) != nil) { [(x) release]; (x) = nil; }

#endif


=====

// Utils.m

#import "Utils.h"



@implementation Utils


+(void)bind:(id)src

  keyPath:(NSString *)srcKey

  to:(id)dest

  keyPath:(id)destKey

  continuous:(BOOL)continuous

  twoWay:(BOOL)twoWay

{

NSMutableDictionary * options =nil;

if (continuous ==YES)

{

options = [[NSMutableDictionaryalloc] init];

[options setObject:[NSNumbernumberWithBool:YES]

forKey:NSContinuouslyUpdatesValueBindingOption];

}

[src bind:srcKeytoObject:dest withKeyPath:destKeyoptions:options];

if (twoWay ==YES)

[dest bind:destKeytoObject:src withKeyPath:srcKeyoptions:options];


[options release];

}


+(NSMutableParagraphStyle *)defaultParagraphStyle

{

return [[[NSParagraphStyledefaultParagraphStyle] mutableCopy]autorelease];

}


+(NSSize)stringSize:(NSString *)string withAttribute:(NSDictionary *)attributes

{

NSAttributedString * attributedString = [NSAttributedStringalloc];

attributedString = [attributedString initWithString:string];

NSSize size = [attributedStringsize];

[attributedString release];

return size;

}


@end

===========

以上是Utils里面的类,一共5个类,10个文件,大家拷贝后,分拆的时候不要忘记检查啊。


在文件夹ImageBrowserView里面有4个类,8个文件,总共18个文件。

以下是代码:



// ImageDataSource.h


#import <Cocoa/Cocoa.h>

#import "../Utils/FSEventsListener.h"



@class IKImageBrowserView;

@class ImageBrowser;



/**

This is the image data source. It's responsible for giving access to all

the images contained in a single folder.

*/

@interface ImageDataSource

: NSObject<FSEventListenerDelegate >

{

@private


/// the current directory. It's bound to the currently selected directory

NSString * mCurrentDirectory;


/// the associated view

ImageBrowser * mImageBrowser;


/// the images' paths.

NSMutableArray * mImages;

}


@property (assign)IBOutlet ImageBrowser *imageBrowser;

@property (readonly)NSArray *images;

@property (readwrite)BOOL isEmpty;


-(id)init;

-(void)dealloc;


// implementation of FSEventListenerDelegate protocol

-(void)fileWasAdded:(NSString *)file;

-(void)fileWasRemoved:(NSString *)file;

-(void)fileWasRenamed:(NSString *)oldFile to:(NSString *)newFile;

-(void)directoryWasAdded:(NSString *)directory;

-(void)directoryWasRemoved:(NSString *)directory;

-(void)directoryWasRenamed:(NSString *)oldDirectory to:(NSString *)newDirectory;


// this is used to bind the directory browser and the image data source

-(NSString *)currentDirectory;

-(void)setCurrentDirectory:(NSString *)path;


// these are internally used

-(void)addImage:(NSString *)path;

-(void)addImagesInPath:(NSString *)path;


// implementation of IKImageBrowserDataSource protocol

-(NSUInteger)numberOfItemsInImageBrowser:(IKImageBrowserView *)view;

-(id)imageBrowser:(IKImageBrowserView *)view itemAtIndex:(NSUInteger)index;


// utility

-(NSInteger)indexOfImage:(NSString *)image;

-(NSArray *)imagesAtIndexes:(NSIndexSet *)indexes;

-(void)setImagesPhoneID;

-(void)setImagesPhonePath;


@end

=======


//ImageDataSource.m


#import <Quartz/Quartz.h>

#import "ImageDataSource.h"

#import "ImageItem.h"

#import "ImageBrowser.h"

#import "../Utils/FileUtils.h"

#import "../Utils/FSEventsListener.h"

#import "../Utils/Utils.h"



@implementation ImageDataSource


@synthesize imageBrowser= mImageBrowser;

@synthesize images= mImages;

@synthesize isEmpty;


-(id)init

{

self = [superinit];

if (self !=nil)

{

mCurrentDirectory= nil;

mImages= [[NSMutableArray alloc] init];

[selfsetIsEmpty:YES];

}

returnself;

}


-(void)dealloc

{

[mCurrentDirectoryrelease];

[mImagesrelease];

[superdealloc];

}


-(NSString *)currentDirectory

{

returnmCurrentDirectory;

}


-(void)setCurrentDirectory:(NSString *)path

{

if (path !=mCurrentDirectory && path != nil)

{

// unregister from the event listeners

[[FSEventsListenerinstance] removeListener:selfforPath:mCurrentDirectory];


// copy the new path

[mCurrentDirectoryrelease];

mCurrentDirectory = [pathcopy];


// load images

[selfsetIsEmpty:YES];

[mImagesremoveAllObjects];

        

[selfaddImagesInPath:mCurrentDirectory];

[mImageBrowserreloadData];


// register with the new path

[[FSEventsListenerinstance] addListener:selfforPath:mCurrentDirectory];

}

}


-(void)addImagesInPath:(NSString *)path

{

// get the content of the directory

NSFileManager * fileManager = [NSFileManagerdefaultManager];

NSURL * url = [NSURLfileURLWithPath:path];

NSArray * content = [fileManagercontentsOfDirectoryAtURL:url

includingPropertiesForKeys:nil

options:NSDirectoryEnumerationSkipsHiddenFiles

error:nil];


// for each item, create an image object and add to the mImportedImages array

for (NSURL * urlin content)

{

[self addImage:[url path]];

}

}


-(void)addImage:(NSString *)path

{

// error check

if ([FileUtilsisImage:path] == NO)

return;


// add the image item

ImageItem * image = [[ImageItemalloc] init];

[image setPath:path];

[mImages addObject:image];

[image release];

[selfsetIsEmpty:NO];

}


-(void)setImagesPhoneID

{

    int images_count = (int)[mImagescount];

    NSString *id_value=nil;

    for (int i=0; i<images_count;i++)

    {

        ImageItem *image1 = [mImagesobjectAtIndex:i];

        id_value = image1.title;

        id_value = [id_value stringByDeletingPathExtension];

        [image1 setPhoto_ID_OnPhone:id_value];

    }

}


-(void)setImagesPhonePath

{

    int images_count = (int)[mImagescount];

    NSString *id_value=nil;

    for (int i=0; i<images_count;i++)

    {

        ImageItem *image1 = [mImagesobjectAtIndex:i];

        id_value = [NSString stringWithFormat:@"AAA%d",i];

        [image1 setPhoto_Path_OnPhone:id_value];

    }

}


-(void)fileWasAdded:(NSString *)file

{

[self addImage:file];

[mImageBrowserreloadDataAndKeepSelection];

}


-(void)fileWasRemoved:(NSString *)file

{

NSInteger index = [selfindexOfImage:file];

if (index == -1)

{

DEBUG_LOG(@"ImageDataSource - receive fileWasRemoved, "

  @"but couldn't find the image [%@]", file);

return;

}


[mImagesremoveObjectAtIndex:index];

[mImageBrowserreloadDataAndKeepSelection];

[self setIsEmpty:[mImages count] > 0 ? NO : YES];

}


-(void)fileWasRenamed:(NSString *)oldFile to:(NSString *)newFile

{

NSInteger index = [selfindexOfImage:oldFile];

if (index == -1)

{

// check if the newFile is an image, and if it's the case, add it.

if ([FileUtilsisImage:newFile] == YES)

[self fileWasAdded:newFile];

return;

}

if ([FileUtilsisImage:newFile] == YES)

{

ImageItem * image = [selfimageBrowser:mImageBrowseritemAtIndex:index];

[image setPath:newFile];

[mImageBrowserreloadDataAndKeepSelection];

}

else

{

[self fileWasRemoved:oldFile];

}

}


-(void)directoryWasAdded:(NSString *)directory

{

}


-(void)directoryWasRemoved:(NSString *)directory

{

}


-(void)directoryWasRenamed:(NSString *)oldDirectory to:(NSString *)newDirectory

{

}


-(NSUInteger)numberOfItemsInImageBrowser:(IKImageBrowserView *)view

{

    return [mImagescount];

}


-(id)imageBrowser:(IKImageBrowserView *)view itemAtIndex:(NSUInteger)index

{

    return [mImagesobjectAtIndex:index];

}


-(NSInteger)indexOfImage:(NSString *)image

{

NSInteger index =0;

for (ImageItem * itemin mImages)

{

if ([[itempath] isEqualToString:image])

return index;

++index;

}

return -1;

}


-(NSArray *)imagesAtIndexes:(NSIndexSet *)indexes

{

NSMutableArray * images = [NSMutableArrayarrayWithCapacity:[indexes count]];

NSUInteger index = [indexesfirstIndex];

while (index !=NSNotFound)

{

[images addObject:[selfimageBrowser:nilitemAtIndex:index]];

index = [indexes indexGreaterThanIndex:index];

}

return images;

}


- (IBAction)OnBT_SetPahtAndShowImages:(id)sender

{

    NSString *path =@"/Users/mac2/Documents/test_photo";

    

    [selfsetCurrentDirectory:path];

    [selfOnBT_ChangeTitle:nil];

}

- (IBAction)OnBT_SetPath2:(id)sender

{

    NSString *path =@"/Users/mac2/Documents/photo1";

    

    [selfsetCurrentDirectory:path];

    [selfOnBT_ChangeTitle:nil];

}

- (IBAction)OnBT_Selected_All:(id)sender

{

    [mImageBrowserselectAll:nil];

}


- (IBAction)OnBT_Selected_None:(id)sender

{

      [mImageBrowserdeselectAll:nil];

}

- (IBAction)OnBT_GetSelectedList:(id)sender

{

    [selfsetImagesPhoneID];

    [selfsetImagesPhonePath];

    NSLog(@"===Path \n==");

    NSArray *files_selected ;

    files_selected = [mImageBrowser selectedImagesAsURLArray];

    NSString *path=nil;

    for (int i=0; i<files_selected.count; i++)

    {

        path = [files_selected objectAtIndex:i] ;

        NSLog(@"\n(%d)%@\n",i+1,path);

    }

    

    NSLog(@"\n===Title \n==");


    files_selected = [mImageBrowserselectedImagesAsTitelArray];

    NSString *title=nil;

    for (int i=0; i<files_selected.count; i++)

    {

        title = [files_selected objectAtIndex:i] ;

         NSLog(@"\n(%d)%@\n",i+1,title);

    }

    

    NSLog(@"\n Photo ID On Phone \n");


    files_selected = [mImageBrowserselectedImagesAsPhotoIDArray];

    for (int i=0; i<files_selected.count; i++)

    {

        title = [files_selected objectAtIndex:i] ;

        NSLog(@"\n(%d)%@\n",i+1,title);

    }

    

    NSLog(@"\n Photo Path On Phone \n");

    

    files_selected = [mImageBrowserselectedImagesAsPhotoPathArray];

    for (int i=0; i<files_selected.count; i++)

    {

        title = [files_selected objectAtIndex:i] ;

        NSLog(@"\n(%d)%@\n",i+1,title);

    }

}


- (IBAction)OnBT_ChangeTitle:(id)sender

{

    [selfsetImagesPhoneID]; //OK

    [selfsetImagesPhonePath];//OK

    

    // change title

    int images_count = (int)[mImagescount];

    NSString *id_value=nil;

    for (int i=0; i<images_count;i++)

    {

        ImageItem *image1 = [mImagesobjectAtIndex:i];

        id_value = image1.Photo_Path_OnPhone;

        [image1 setTitle:id_value];

    }

    //refresh

    [mImageBrowserreloadData];

}


@end

======


// ImageItem.h


#import <Cocoa/Cocoa.h>


/**

This class represents a single image.

*/

@interface ImageItem

: NSObject

{


@private


/// the path to the image file

NSString * mPath;


/// the title of the image. Usually the file name.

NSString * mTitle;

    

    NSString *mPhoto_ID_OnPhone;

    NSString *mPhoto_Path_OnPhone;


}


-(void)setPath:(NSString *)path;

-(NSString *)path;

-(void)setTitle:(NSString *)title;

-(NSString *)title;



-(NSString *)Photo_ID_OnPhone;

-(NSString *)Photo_Path_OnPhone;


-(void)setPhoto_ID_OnPhone:(NSString *)photo_id;

-(void)setPhoto_Path_OnPhone:(NSString *)photo_path;


// implementation of IKImageBrowserItem protocol

-(NSString *)imageRepresentationType;

-(id)imageRepresentation;

-(NSString *)imageUID;

-(NSString *)imageTitle;


@end

======


// ImageItem.m


#import "ImageItem.h"

#import <Quartz/Quartz.h>



@implementation ImageItem



-(void)dealloc

{

[mPathrelease];

[mTitlerelease];

    [mPhoto_Path_OnPhonerelease];

    [mPhoto_ID_OnPhonerelease];

    

    [super dealloc];

}


-(void)setPath:(NSString *)path

{

if (mPath != path)

{

[mPathrelease];

[mTitlerelease];

mPath= [path retain];

mTitle= [[mPathlastPathComponent] copy];

}

}

-(NSString *)Photo_ID_OnPhone;

{

returnmPhoto_ID_OnPhone;

}


-(NSString *)Photo_Path_OnPhone

{

returnmPhoto_Path_OnPhone;

}

-(NSString *)path

{

returnmPath;

}


-(void)setPhoto_ID_OnPhone:(NSString *)photo_id

{

    if (mPhoto_ID_OnPhone != photo_id)

{

[mPhoto_ID_OnPhonerelease];

mPhoto_ID_OnPhone= [photo_id retain];

}

}

-(void)setPhoto_Path_OnPhone:(NSString *)photo_path

{

    if (mPhoto_Path_OnPhone != photo_path)

{

[mPhoto_Path_OnPhonerelease];

mPhoto_Path_OnPhone= [photo_path retain];

}

}


-(void)setTitle:(NSString *)title

{

if (mTitle != title)

{

[mTitlerelease];

mTitle = [titlecopy];

}

}


-(NSString *)title

{

returnmTitle;

}


-(NSString *)imageRepresentationType

{

returnIKImageBrowserPathRepresentationType;

}


-(id)imageRepresentation

{

returnmPath;

}


-(NSString *)imageUID

{

returnmPath;

}


-(NSString *)imageTitle

{

if (mTitle ==nil)

return [mPathlastPathComponent];

returnmTitle;

}


@end

=====


//ImageBrowser.h



#import <Quartz/Quartz.h>



@class ImageItem;



/**

Image browser view. Displays thumbnails of the images contained in a single

folder. Fullscreen is binded to the image view, and it implements the

CutCopy protocol.

*/

@interface ImageBrowser :IKImageBrowserView

{

    

}


-(void)awakeFromNib;

-(void)reloadData;

-(void)reloadDataAndKeepSelection;


// utils

-(BOOL)setFullscreen;

-(void)deleteSelectedImages;

-(void)cutSelectedImages;

-(void)copySelectedImages;

-(IBAction)selectAll:(id)sender;

-(IBAction)deselectAll:(id)sender;

-(void)setSelectedImage:(NSString *)image;

-(ImageItem *)itemAtIndex:(NSUInteger)index;

-(NSArray *)selectedImagesAsURLArray;

-(NSArray *)selectedImagesAsTitelArray;

-(NSArray *)selectedImagesAsPhotoIDArray;


-(NSArray *)selectedImagesAsPhotoPathArray;


// used by the slide show timer

-(void)selectNextImage:(NSTimer *)timer;


// for binding

-(BOOL)showTitles;

-(void)setShowTitles:(BOOL)showTitles;

-(float)thumbnailMargin;

-(void)setThumbnailMargin:(BOOL)margin;


// event methods

-(void)keyDown:(NSEvent *)theEvent;

-(void)otherMouseDown:(NSEvent *)theEvent;


@end

====

//ImageBrowser.m


#import "ImageBrowser.h"

#import "ImageBrowserDelegate.h"

#import "ImageItem.h"

#import "ImageDataSource.h"

#import "../Utils/FileUtils.h"

#import "../Utils/Utils.h"

#import "../Utils/SlideShow.h"


@implementation ImageBrowser


-(void)awakeFromNib

{

// cell spacing

    // [LeftRight Margin,UpDown Margin]

[selfsetIntercellSpacing:NSMakeSize(2.0f,4.0f)];


    // forground color for the cell's titles

NSMutableDictionary * options = [[NSMutableDictionaryalloc] init];

[options setObject:[NSColorblackColor]forKey:NSForegroundColorAttributeName];

[selfsetValue:optionsforKey:IKImageBrowserCellsTitleAttributesKey];

[options release];

    

    [selfsetShowTitles :YES];

}


-(void)dealloc

{

[superdealloc];

}


/**

This method is used to seemlessly reload data. Since the selected image is

bound to the current image of the image view, when we do the usual

reloadData, the selection is lost. If we're in fullscreen, it'll break it.

So this method reloads data and select the next available image just after

that.

*/

-(void)reloadDataAndKeepSelection

{

// remember the first selected image

int selectedIndex = (int)[[selfselectionIndexes] firstIndex];


// reload the data

[(ImageBrowserDelegate *)[selfdelegate] setIgnoreSelectionChanges:YES];

[superreloadData];

[(ImageBrowserDelegate *)[selfdelegate] setIgnoreSelectionChanges:NO];


// restore the selection, taking care of out of bound indexes

int numImages = (int)[[selfdataSource] numberOfItemsInImageBrowser:self];

if (numImages !=0)

{

if (selectedIndex >= numImages)

selectedIndex = numImages - 1;

[selfsetSelectionIndexes:[NSIndexSetindexSetWithIndex:selectedIndex]

  byExtendingSelection:NO];

}

else

{

// if there is no more images, we need to explicitely set the image

// property of the delegate to nil.ImageViewer

// This is because [super reloadData] set the current selection to

// nothing, so setting it again to nothing will NOT call the selection

// changed delegate, thus the need to explicitely call setSelectedImage.

[(ImageBrowserDelegate *)[selfdelegate] setSelectedImage:nil];

}

}


-(void)reloadData

{

[superreloadData];

[selfscrollPoint:NSMakePoint(0, [selfframe].size.height)];

}


-(void)selectNextImage:(NSTimer *)timer

{

// get the index of the first selected image

int selectedImage = -1;

if ([selfselectionIndexes] != nil || [[selfselectionIndexes] count] !=0)

selectedImage = (int)[[selfselectionIndexes] firstIndex];


// increment it, and check for bound, and loop

++selectedImage;

int numImages = (int)[[selfdataSource] numberOfItemsInImageBrowser:nil];

if (selectedImage >= numImages)

{

if ([[timeruserInfo] boolValue] ==YES)

{

selectedImage = 0;

}

else

{

selectedImage = (int)numImages -1;

// also stop the slide show

[SlideShowstopSlideShow];

}

}


// finally, set the new image

[selfsetSelectionIndexes:[NSIndexSetindexSetWithIndex:selectedImage]

  byExtendingSelection:NO];

}


-(BOOL)showTitles

{

return [selfcellsStyleMask] & IKCellsStyleTitled;

}


-(void)setShowTitles:(BOOL)showTitles

{

if (showTitles ==YES)

[selfsetCellsStyleMask:[selfcellsStyleMask] | IKCellsStyleTitled];

else

[selfsetCellsStyleMask:[selfcellsStyleMask] & ~IKCellsStyleTitled];

}


-(float)thumbnailMargin

{

return [selfintercellSpacing].width;

}


-(void)setThumbnailMargin:(BOOL)margin

{

[selfsetIntercellSpacing:NSMakeSize(margin, margin)];

}


-(BOOL)setFullscreen

{

// if still nothing's selected, it means we don't have any image

// in the image browser, so simply break (launching a slideshow

// on an empty folder has no meaning :)

if ([selfselectionIndexes] == nil ||

[[selfselectionIndexes] count] ==0)

returnNO;


// select only the first one

[selfsetSelectionIndexes:[NSIndexSetindexSetWithIndex:[[selfselectionIndexes] firstIndex]]

  byExtendingSelection:NO];


// set the fullscreen property of the delegate (which is binded to the

// image view)

[(ImageBrowserDelegate *)[selfdelegate] setFullscreen:YES];

returnYES;

}


-(ImageItem *)itemAtIndex:(NSUInteger)index

{

return [[selfdataSource] imageBrowser:selfitemAtIndex:index];

}


-(NSArray *)selectedImagesAsURLArray

{

NSIndexSet * indexes = [selfselectionIndexes];

NSUInteger index = [indexesfirstIndex];

NSMutableArray * files = [NSMutableArrayarrayWithCapacity:[indexescount]];

while (index !=NSNotFound)

{

[files addObject:[NSURLfileURLWithPath:[[selfitemAtIndex:index] path]]];

index = [indexes indexGreaterThanIndex:index];

}

return files;

}


-(NSArray *)selectedImagesAsTitelArray

{

NSIndexSet * indexes = [selfselectionIndexes];

NSUInteger index = [indexesfirstIndex];

NSMutableArray * files = [NSMutableArrayarrayWithCapacity:[indexescount]];

while (index !=NSNotFound)

{

[files addObject:[[selfitemAtIndex:index] title]];

index = [indexes indexGreaterThanIndex:index];

}

return files;

}


-(NSArray *)selectedImagesAsPhotoIDArray

{

NSIndexSet * indexes = [selfselectionIndexes];

NSUInteger index = [indexesfirstIndex];

NSMutableArray * files = [NSMutableArrayarrayWithCapacity:[indexescount]];

while (index !=NSNotFound)

{

[files addObject:[[selfitemAtIndex:index] Photo_ID_OnPhone]];

index = [indexes indexGreaterThanIndex:index];

}

return files;

}


-(NSArray *)selectedImagesAsPhotoPathArray

{

NSIndexSet * indexes = [selfselectionIndexes];

NSUInteger index = [indexesfirstIndex];

NSMutableArray * files = [NSMutableArrayarrayWithCapacity:[indexescount]];

while (index !=NSNotFound)

{

[files addObject:[[selfitemAtIndex:index] Photo_Path_OnPhone]];

index = [indexes indexGreaterThanIndex:index];

}

return files;

}

-(void)deleteSelectedImages

{

// remove files from the disk

NSArray * files = [selfselectedImagesAsURLArray];

for (NSURL * filein files)

[[FileUtilsinstance] removeItemAtPath:[filepath]];

}


-(void)cutSelectedImages

{

[[FileUtilsinstance] cutItems:[selfselectedImagesAsURLArray]];

}


-(void)copySelectedImages

{

[[FileUtilsinstance] copyItems:[selfselectedImagesAsURLArray]];

}


-(void)setSelectedImage:(NSString *)image

{

[(ImageBrowserDelegate *)[selfdelegate] setSelectedImage:image];

}


-(IBAction)selectAll:(id)sender

{

// check if we're not in fullscreen

if ([(ImageBrowserDelegate *)[selfdelegate] fullscreen] == YES)

return;


int numImages = (int)[[selfdataSource] numberOfItemsInImageBrowser:self];

if (numImages ==0)

return;


// ensure the image browser is the first responder when it selects all

[[selfwindow] makeFirstResponder:self];


NSIndexSet * indexSet = [NSIndexSetindexSetWithIndexesInRange:NSMakeRange(0, numImages)];

[selfsetSelectionIndexes:indexSet byExtendingSelection:NO];

}


-(IBAction)deselectAll:(id)sender

{

// check if we're not in fullscreen

if ([(ImageBrowserDelegate *)[selfdelegate] fullscreen] == YES)

return;


[selfsetSelectionIndexes:nilbyExtendingSelection:NO];

}


-(void)keyDown:(NSEvent *)theEvent

{

// get the event and the modifiers

NSString * characters = [theEventcharactersIgnoringModifiers];

unichar event = [characterscharacterAtIndex:0];


switch (event)

{

// space & p : play / pause slideshow

case ' ':

case 'p':

if ([SlideShowisRunning] == YES)

{

[SlideShowstopSlideShow];

}

else

{

if ([selfsetFullscreen] == YES)

[SlideShowstartSlideShow:selfcallback:@"selectNextImage:"];

}

break;


// enter & escape : leave fullscreen

case 13:

case 27:

[selfsetFullscreen];

break;


default:

[super keyDown:theEvent];

}

}


-(void)otherMouseDown:(NSEvent *)theEvent

{

if ([theEventclickCount] == 1)

[selfsetFullscreen];

}


@end

====

//ImageBrowserDelegate.h


#import <Cocoa/Cocoa.h>


@class IKImageBrowserView;

@class ImageBrowser;


@interface ImageBrowserDelegate: NSObject

{


@private


NSString *mSelectedImage;

ImageBrowser *mImageBrowser;

BOOLmIgnoreSelectionChanges;


}


@property BOOLignoreSelectionChanges;

@property BOOLfullscreen;

@property (assign)IBOutlet ImageBrowser *imageBrowser;


-(id)init;

-(void)dealloc;


// used to bind the image view and the image browser view

-(NSString *)selectedImage;

-(void)setSelectedImage:(NSString *)image;


// implementation of IKImageBrowserDelegate protocol

-(void)imageBrowserSelectionDidChange:(IKImageBrowserView *)aBrowser;

-(void)imageBrowser:(IKImageBrowserView *)aBrowser cellWasDoubleClickedAtIndex:(NSUInteger)index;

-(NSUInteger)imageBrowser:(IKImageBrowserView *)aBrowser writeItemsAtIndexes:(NSIndexSet *)itemIndexes toPasteboard:(NSPasteboard *)pasteboard;


@end

=====


//ImageBrowserDelegate.m


#import <Quartz/Quartz.h>


#import "ImageBrowserDelegate.h"

#import "ImageBrowser.h"

#import "ImageDataSource.h"

#import "ImageItem.h"

#import "../Utils/Utils.h"


@implementation ImageBrowserDelegate


@synthesize fullscreen;

@synthesize ignoreSelectionChanges= mIgnoreSelectionChanges;

@synthesize imageBrowser= mImageBrowser;


-(id)init

{

self = [superinit];

if (self !=nil)

{

mSelectedImage= nil;

mIgnoreSelectionChanges= NO;

}

returnself;

}


-(void)dealloc

{

if (mSelectedImage !=nil)

{

[mSelectedImagerelease];

mSelectedImage =nil;

}

[superdealloc];

}


-(NSString *)selectedImage

{

returnmSelectedImage;

}


-(void)setSelectedImage:(NSString *)image

{

if (mSelectedImage != image)

{

// NOTE: here, we check if the image if different from the current one.

//This means that if we reach this point, the selected image was

//set by an external source (by binding or whatever)

//This is also why we need to scroll the view to show the new

//selected image.

if (mSelectedImage !=nil)

[mSelectedImagerelease];

mSelectedImage = [imagecopy];


// update the selected image of the view

ImageDataSource *dataSource = (ImageDataSource *)[mImageBrowserdataSource];

// get the index corresponding to the image

NSInteger imageIndex = [dataSourceindexOfImage:image];

NSIndexSet * indices = [NSIndexSetindexSetWithIndex:imageIndex];

[mImageBrowsersetSelectionIndexes:indices byExtendingSelection:NO];

// scroll to selected image

[mImageBrowserscrollIndexToVisible:imageIndex];

}

}


-(void)imageBrowserSelectionDidChange:(IKImageBrowserView *)aBrowser

{

if (mIgnoreSelectionChanges ==YES)

return;


// get the selection indexes

NSIndexSet * selectionIndexes = [mImageBrowserselectionIndexes];


// set the first selected image, so that any other view bound to

// selectedImage will be notified

if ([selectionIndexescount] == 0)

{

[selfsetSelectedImage:nil];

}

else

{

NSUInteger index = [selectionIndexesfirstIndex];

ImageItem * item = [[mImageBrowserdataSource]imageBrowser:nil

  itemAtIndex:index];

[mSelectedImagerelease];

mSelectedImage = [[itempath] copy];

        NSLog(@"\nPath:\n%@",[itempath]);

        NSLog(@"\nTitel:\n%@",[itemtitle]);

[selfsetSelectedImage:[item path]];

}

}


-(void)imageBrowser:(IKImageBrowserView *)aBrowser cellWasDoubleClickedAtIndex:(NSUInteger)index

{

// NOTE: the fullscreen property of this instance is bound to the fullscreen

//property of the image view, so this will automatically toggle

//fullscreen without having a direct reference to ImageView

[selfsetFullscreen:![selffullscreen]];

}


-(NSUInteger)imageBrowser:(IKImageBrowserView *)aBrowser

writeItemsAtIndexes:(NSIndexSet *)itemIndexes

toPasteboard:(NSPasteboard *)pasteboard

{

NSArray * selectedImages = [mImageBrowserselectedImagesAsURLArray];

[pasteboard clearContents];

[pasteboard writeObjects:selectedImages];

return [selectedImagescount];

}



@end


代码结束!

需要说明的是:

需要从控件里面找到2个委托图标,然后分别跟ImageDataSource和ImageBrowserDelegate绑定。然后,控件的定义,分别在这两个类里面都要说明。

在数据源里面设置

ImageDataSource *g_ImageDataSource;

这样一个变量并且在

-(id)init

{

self = [superinit];

if (self !=nil)

{

        

mCurrentDirectory= nil;

mImages= [[NSMutableArray alloc] init];

[selfsetIsEmpty:YES];

        g_ImageDataSource =self;

        isSelectedAll =NO;

}

returnself;

}

初始化这样在外部就可以对整个控件调用了比如动态修改图片路径。

以上测试在MAC的OSX10.8.5的XCode 4.6上测试成功。

注意本应用是OSX应用,不是iOS手机应用。

运行在苹果系统的电脑上。


2014-11-13 Created By DMD

ShenZhen, China

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值