Index: window_cocoa.mm =================================================================== --- window_cocoa.mm (revision 3177) +++ window_cocoa.mm (working copy) @@ -41,9 +41,39 @@ // //M*/ +#import + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +/*** begin IPhone OS Stubs ***/ +// When highgui functions are referred to on iPhone OS, they will fail silently. +CV_IMPL int cvInitSystem( int argc, char** argv) { return 0;} +CV_IMPL int cvStartWindowThread(){ return 0; } +CV_IMPL void cvDestroyWindow( const char* name) {} +CV_IMPL void cvDestroyAllWindows( void ) {} +CV_IMPL void cvShowImage( const char* name, const CvArr* arr) {} +CV_IMPL void cvResizeWindow( const char* name, int width, int height) {} +CV_IMPL void cvMoveWindow( const char* name, int x, int y){} +CV_IMPL int cvCreateTrackbar (const char* trackbar_name,const char* window_name, + int* val, int count, CvTrackbarCallback on_notify) {return 0;} +CV_IMPL int cvCreateTrackbar2(const char* trackbar_name,const char* window_name, + int* val, int count, CvTrackbarCallback2 on_notify2, void* userdata) {return 0;} +CV_IMPL void cvSetMouseCallback( const char* name, CvMouseCallback function, void* info) {} +CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) {return 0;} +CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos) {} +CV_IMPL void* cvGetWindowHandle( const char* name ) {return NULL;} +CV_IMPL const char* cvGetWindowName( void* window_handle ) {return NULL;} +CV_IMPL int cvNamedWindow( const char* name, int flags ) {return 0; } +CV_IMPL int cvWaitKey (int maxWait) {return 0;} +//*** end IphoneOS Stubs ***/ +#else + + #import #include "precomp.hpp" +#include +using namespace std; + const int TOP_BORDER = 7; static NSApplication *application = nil; @@ -54,7 +84,7 @@ @interface CVView : NSView { NSImage *image; } -@property(assign) NSImage *image; +@property(retain) NSImage *image; - (void)setImageData:(CvArr *)arr; @end @@ -66,8 +96,8 @@ CvTrackbarCallback callback; CvTrackbarCallback2 callback2; } -@property(assign) NSSlider *slider; -@property(assign) NSTextField *name; +@property(retain) NSSlider *slider; +@property(retain) NSTextField *name; @property(assign) int *value; @property(assign) void *userData; @property(assign) CvTrackbarCallback callback; @@ -79,11 +109,13 @@ CvMouseCallback mouseCallback; void *mouseParam; BOOL autosize; + BOOL firstContent; } @property(assign) CvMouseCallback mouseCallback; @property(assign) void *mouseParam; @property(assign) BOOL autosize; -@property(assign) NSMutableDictionary *sliders; +@property(assign) BOOL firstContent; +@property(retain) NSMutableDictionary *sliders; - (CVView *)contentView; - (void)cvSendMouseEvent:(NSEvent *)event type:(int)type flags:(int)flags; - (void)cvMouseEvent:(NSEvent *)event; @@ -92,9 +124,11 @@ static void icvCocoaCleanup(void) { + //cout << "icvCocoaCleanup" << endl; if( application ) { - [application terminate:nil]; + cvDestroyAllWindows(); + //[application terminate:nil]; application = 0; [pool release]; } @@ -102,6 +136,7 @@ CV_IMPL int cvInitSystem( int argc, char** argv) { + //cout << "cvInitSystem" << endl; wasInitialized = true; pool = [[NSAutoreleasePool alloc] init]; @@ -116,43 +151,61 @@ if( floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5 ) [application setActivationPolicy:0/*NSApplicationActivationPolicyRegular*/]; #endif - [application finishLaunching]; - atexit(icvCocoaCleanup); + //[application finishLaunching]; + //atexit(icvCocoaCleanup); return 0; } CVWindow *cvGetWindow(const char *name) { - NSString *cvname = [NSString stringWithFormat:@"%s", name]; - return (CVWindow *)[windows valueForKey:cvname]; + //cout << "cvGetWindow" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + NSString *cvname = [NSString stringWithFormat:@"%s", name]; + CVWindow* retval = (CVWindow*) [windows valueForKey:cvname] ; + //cout << "retain count: " << [retval retainCount] << endl; + //retval = [retval retain]; + //cout << "retain count: " << [retval retainCount] << endl; + [localpool drain]; + //cout << "retain count: " << [retval retainCount] << endl; + return retval; } CV_IMPL int cvStartWindowThread() { + //cout << "cvStartWindowThread" << endl; return 0; } CV_IMPL void cvDestroyWindow( const char* name) { + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + //cout << "cvDestroyWindow" << endl; CVWindow *window = cvGetWindow(name); if(window) { [window performClose:nil]; [windows removeObjectForKey:[NSString stringWithFormat:@"%s", name]]; } + [localpool drain]; } CV_IMPL void cvDestroyAllWindows( void ) { + //cout << "cvDestroyAllWindows" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; for(NSString *key in windows) { [[windows valueForKey:key] performClose:nil]; } [windows removeAllObjects]; + [localpool drain]; } CV_IMPL void cvShowImage( const char* name, const CvArr* arr) { + //cout << "cvShowImage" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; CVWindow *window = cvGetWindow(name); if(!window) { @@ -167,21 +220,28 @@ NSRect vrectOld = [[window contentView] frame]; [[window contentView] setImageData:(CvArr *)arr]; - if(/*[window autosize] ||*/ empty) + if([window autosize] || [window firstContent] || empty) { NSRect vrectNew = vrectOld; vrectNew.size = [[[window contentView] image] size]; rect.size.width += vrectNew.size.width - vrectOld.size.width; rect.size.height += vrectNew.size.height - vrectOld.size.height; + rect.origin.y -= vrectNew.size.height - vrectOld.size.height; + [window setFrame:rect display:YES]; } else [window display]; + [window setFirstContent:NO]; } + [localpool drain]; } CV_IMPL void cvResizeWindow( const char* name, int width, int height) { + + //cout << "cvResizeWindow" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; CVWindow *window = cvGetWindow(name); if(window) { NSRect frame = [window frame]; @@ -189,23 +249,27 @@ frame.size.height = height; [window setFrame:frame display:YES]; } + [localpool drain]; } CV_IMPL void cvMoveWindow( const char* name, int x, int y) { + CV_FUNCNAME("cvMoveWindow"); __BEGIN__; + NSAutoreleasePool* localpool1 = [[NSAutoreleasePool alloc] init]; CVWindow *window = nil; if(name == NULL) CV_ERROR( CV_StsNullPtr, "NULL window name" ); - + //cout << "cvMoveWindow"<< endl; window = cvGetWindow(name); if(window) { y = [[window screen] frame].size.height - y; [window setFrameTopLeftPoint:NSMakePoint(x, y)]; } + [localpool1 drain]; __END__; } @@ -216,15 +280,20 @@ CvTrackbarCallback on_notify) { CV_FUNCNAME("cvCreateTrackbar"); + int result = 0; CVWindow *window = nil; + NSAutoreleasePool* localpool2 = nil; __BEGIN__; + if (localpool2 != nil) [localpool2 drain]; + localpool2 = [[NSAutoreleasePool alloc] init]; if(window_name == NULL) CV_ERROR( CV_StsNullPtr, "NULL window name" ); + //cout << "cvCreateTrackbar" << endl ; window = cvGetWindow(window_name); if(window) { [window createSliderWithName:trackbar_name @@ -233,7 +302,7 @@ callback:on_notify]; result = 1; } - + [localpool2 drain]; __END__; return result; } @@ -245,12 +314,15 @@ CvTrackbarCallback2 on_notify2, void* userdata) { + //cout <<"cvCreateTrackbar2" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; int res = cvCreateTrackbar(trackbar_name, window_name, val, count, NULL); if(res) { CVSlider *slider = [[cvGetWindow(window_name) sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]]; [slider setCallback2:on_notify2]; [slider setUserData:userdata]; } + [localpool drain]; return res; } @@ -261,9 +333,13 @@ CV_FUNCNAME("cvSetMouseCallback"); CVWindow *window = nil; - + NSAutoreleasePool* localpool3 = nil; __BEGIN__; + //cout << "cvSetMouseCallback" << endl; + if (localpool3 != nil) [localpool3 drain]; + localpool3 = [[NSAutoreleasePool alloc] init]; + if(name == NULL) CV_ERROR( CV_StsNullPtr, "NULL window name" ); @@ -272,6 +348,7 @@ [window setMouseCallback:function]; [window setMouseParam:info]; } + [localpool3 drain]; __END__; } @@ -282,12 +359,16 @@ CVWindow *window = nil; int pos = -1; - + NSAutoreleasePool* localpool4 = nil; __BEGIN__; + //cout << "cvGetTrackbarPos" << endl; if(trackbar_name == NULL || window_name == NULL) CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); + if (localpool4 != nil) [localpool4 drain]; + localpool4 = [[NSAutoreleasePool alloc] init]; + window = cvGetWindow(window_name); if(window) { CVSlider *slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]]; @@ -295,7 +376,7 @@ pos = [[slider slider] intValue]; } } - + [localpool4 drain]; __END__; return pos; } @@ -306,15 +387,19 @@ CVWindow *window = nil; CVSlider *slider = nil; + NSAutoreleasePool* localpool5 = nil; __BEGIN__; - + //cout << "cvSetTrackbarPos" << endl; if(trackbar_name == NULL || window_name == NULL) CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" ); if(pos <= 0) CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" ); + if (localpool5 != nil) [localpool5 drain]; + localpool5 = [[NSAutoreleasePool alloc] init]; + window = cvGetWindow(window_name); if(window) { slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]]; @@ -322,22 +407,29 @@ [[slider slider] setIntValue:pos]; } } + [localpool5 drain]; __END__; } CV_IMPL void* cvGetWindowHandle( const char* name ) { + //cout << "cvGetWindowHandle" << endl; return cvGetWindow(name); } CV_IMPL const char* cvGetWindowName( void* window_handle ) { + //cout << "cvGetWindowName" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; for(NSString *key in windows) { - if([windows valueForKey:key] == window_handle) + if([windows valueForKey:key] == window_handle) { + [localpool drain]; return [key UTF8String]; + } } + [localpool drain]; return 0; } @@ -346,21 +438,39 @@ if( !wasInitialized ) cvInitSystem(0, 0); + //cout << "cvNamedWindow" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; CVWindow *window = cvGetWindow(name); if( window ) { [window setAutosize:(flags == CV_WINDOW_AUTOSIZE)]; + [localpool drain]; return 0; } - - window = [[CVWindow alloc] initWithContentRect:NSMakeRect(0,0,200,200) - styleMask:NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask| - (!(flags & CV_WND_PROP_AUTOSIZE) ? NSResizableWindowMask : 0) - backing:NSBackingStoreBuffered - defer:NO]; + NSScreen* mainDisplay = [NSScreen mainScreen]; + NSString *windowName = [NSString stringWithFormat:@"%s", name]; + NSUInteger showResize = (flags == CV_WINDOW_AUTOSIZE) ? 0: NSResizableWindowMask ; + NSUInteger styleMask = NSTitledWindowMask|NSMiniaturizableWindowMask|showResize; + CGFloat windowWidth = [NSWindow minFrameWidthWithTitle:windowName styleMask:styleMask]; + NSRect initContentRect = NSMakeRect(0, 0, windowWidth, 0); + if (mainDisplay) { + NSRect dispFrame = [mainDisplay visibleFrame]; + initContentRect.origin.y = dispFrame.size.height-20; + } + + window = [[CVWindow alloc] initWithContentRect:initContentRect + styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|showResize + backing:NSBackingStoreBuffered + defer:YES + screen:mainDisplay]; + + [window setFrameTopLeftPoint:initContentRect.origin]; + + [window setFirstContent:YES]; + [window setContentView:[[CVView alloc] init]]; [window setHasShadow:YES]; @@ -372,23 +482,25 @@ [window setAutosize:(flags == CV_WINDOW_AUTOSIZE)]; [windows setValue:window forKey:windowName]; - + + [localpool drain]; return [windows count]-1; } CV_IMPL int cvWaitKey (int maxWait) { + //cout << "cvWaitKey" << endl; int returnCode = -1; double start = [[NSDate date] timeIntervalSince1970]; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSAutoreleasePool *localpool = [[NSAutoreleasePool alloc] init]; while(true) { if(([[NSDate date] timeIntervalSince1970] - start) * 1000 >= maxWait && maxWait>0) break; //event = [application currentEvent]; - [pool release]; - pool = [[NSAutoreleasePool alloc] init]; + [localpool drain]; + localpool = [[NSAutoreleasePool alloc] init]; NSEvent *event = [application @@ -408,7 +520,7 @@ [NSThread sleepForTimeInterval:1/100.]; } - [pool release]; + [localpool drain]; return returnCode; } @@ -418,9 +530,11 @@ @synthesize mouseCallback; @synthesize mouseParam; @synthesize autosize; +@synthesize firstContent; @synthesize sliders; - (void)cvSendMouseEvent:(NSEvent *)event type:(int)type flags:(int)flags { + //cout << "cvSendMouseEvent" << endl; NSPoint mp = [NSEvent mouseLocation]; NSRect visible = [[self contentView] frame]; mp = [self convertScreenToBase: mp]; @@ -444,6 +558,7 @@ } - (void)cvMouseEvent:(NSEvent *)event { + //cout << "cvMouseEvent" << endl; if(!mouseCallback) return; @@ -464,16 +579,20 @@ if([event type] == NSOtherMouseDragged) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags | CV_EVENT_FLAG_MBUTTON];} } - (void)keyDown:(NSEvent *)theEvent { + //cout << "keyDown" << endl; [super keyDown:theEvent]; } - (void)rightMouseDragged:(NSEvent *)theEvent { + //cout << "rightMouseDragged" << endl ; [self cvMouseEvent:theEvent]; } - (void)rightMouseUp:(NSEvent *)theEvent { + //cout << "rightMouseUp" << endl; [self cvMouseEvent:theEvent]; } - (void)rightMouseDown:(NSEvent *)theEvent { // Does not seem to work? + //cout << "rightMouseDown" << endl; [self cvMouseEvent:theEvent]; } - (void)mouseMoved:(NSEvent *)theEvent { @@ -499,6 +618,7 @@ } - (void)createSliderWithName:(const char *)name maxValue:(int)max value:(int *)value callback:(CvTrackbarCallback)callback { + //cout << "createSliderWithName" << endl; if(sliders == nil) sliders = [[NSMutableDictionary alloc] init]; @@ -512,6 +632,9 @@ CVSlider *slider = [[CVSlider alloc] init]; [[slider name] setStringValue:cvname]; [[slider slider] setMaxValue:max]; + [[slider slider] setMinValue:0]; + [[slider slider] setNumberOfTickMarks:(max+1)]; + [[slider slider] setAllowsTickMarkValuesOnly:YES]; if(value) { [[slider slider] setIntValue:*value]; @@ -527,6 +650,13 @@ // Update slider sizes [[self contentView] setFrameSize:[[self contentView] frame].size]; [[self contentView] setNeedsDisplay:YES]; + + + int height = 0; + for(NSString *key in sliders) { + height += [[sliders valueForKey:key] frame].size.height; + } + [self setContentMinSize:NSMakeSize(0, height)]; } - (CVView *)contentView { @@ -540,12 +670,15 @@ @synthesize image; - (id)init { + //cout << "CVView init" << endl; [super init]; - image = nil; + image = [[NSImage alloc] init]; return self; } - (void)setImageData:(CvArr *)arr { + //cout << "setImageData" << endl; + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; CvMat *arrMat, *cvimage, stub; arrMat = cvGetMat(arr, &stub); @@ -567,41 +700,54 @@ CGImageRef imageRef = CGImageCreate(width, height, size , size*nbChannels , cvimage->step, colorspace, kCGImageAlphaNone , provider, NULL, true, kCGRenderingIntentDefault); - NSBitmapImageRep *bitmap = [[[NSBitmapImageRep alloc] initWithCGImage:imageRef] autorelease]; + NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCGImage:imageRef]; if(image) { [image release]; } + image = [[NSImage alloc] init]; [image addRepresentation:bitmap]; + [bitmap release]; + CGColorSpaceRelease(colorspace); CGDataProviderRelease(provider); + CGImageRelease(imageRef); cvReleaseMat(&cvimage); + [localpool drain]; [self setNeedsDisplay:YES]; + } - (void)setFrameSize:(NSSize)size { + //cout << "setFrameSize" << endl; [super setFrameSize:size]; + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; int height = size.height; - CVWindow *window = (CVWindow *)[self window]; - for(NSString *key in [window sliders]) { - NSSlider *slider = [[window sliders] valueForKey:key]; + CVWindow *cvwindow = (CVWindow *)[self window]; + for(NSString *key in [cvwindow sliders]) { + NSSlider *slider = [[cvwindow sliders] valueForKey:key]; NSRect r = [slider frame]; r.origin.y = height - r.size.height; [slider setFrame:r]; height -= r.size.height; } + [localpool drain]; } - (void)drawRect:(NSRect)rect { - CVWindow *window = (CVWindow *)[self window]; + //cout << "drawRect" << endl; + [super drawRect:rect]; + + NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; + CVWindow *cvwindow = (CVWindow *)[self window]; int height = 0; - for(NSString *key in [window sliders]) { - height += [[[window sliders] valueForKey:key] frame].size.height; + for(NSString *key in [cvwindow sliders]) { + height += [[[cvwindow sliders] valueForKey:key] frame].size.height; } - [super drawRect:rect]; NSRect imageRect = {{0,0}, {self.frame.size.width, self.frame.size.height-height-6}}; @@ -611,6 +757,7 @@ operation: NSCompositeSourceOver fraction: 1.0]; } + [localpool release]; } @@ -671,4 +818,6 @@ @end +#endif + /* End of file. */