1 /* The file is the modified version of window_cocoa.mm from opencv-cocoa project by Andre Cohen */
3 /*M///////////////////////////////////////////////////////////////////////////////////////
5 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
7 // By downloading, copying, installing or using the software you agree to this license.
8 // If you do not agree to this license, do not download, install,
9 // copy or use the software.
13 // For Open Source Computer Vision Library
15 // Copyright (C) 2010, Willow Garage Inc., all rights reserved.
16 // Third party copyrights are property of their respective owners.
18 // Redistribution and use in source and binary forms, with or without modification,
19 // are permitted provided that the following conditions are met:
21 // * Redistribution's of source code must retain the above copyright notice,
22 // this list of conditions and the following disclaimer.
24 // * Redistribution's in binary form must reproduce the above copyright notice,
25 // this list of conditions and the following disclaimer in the documentation
26 // and/or other materials provided with the distribution.
28 // * The name of Intel Corporation may not be used to endorse or promote products
29 // derived from this software without specific prior written permission.
31 // This software is provided by the copyright holders and contributors "as is" and
32 // any express or implied warranties, including, but not limited to, the implied
33 // warranties of merchantability and fitness for a particular purpose are disclaimed.
34 // In no event shall the Intel Corporation or contributors be liable for any direct,
35 // indirect, incidental, special, exemplary, or consequential damages
36 // (including, but not limited to, procurement of substitute goods or services;
37 // loss of use, data, or profits; or business interruption) however caused
38 // and on any theory of liability, whether in contract, strict liability,
39 // or tort (including negligence or otherwise) arising in any way out of
40 // the use of this software, even if advised of the possibility of such damage.
43 #include "precomp.hpp"
45 #import <TargetConditionals.h>
47 #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
48 /*** begin IPhone OS Stubs ***/
49 // When highgui functions are referred to on iPhone OS, they will fail silently.
50 CV_IMPL int cvInitSystem( int argc, char** argv) { return 0;}
51 CV_IMPL int cvStartWindowThread(){ return 0; }
52 CV_IMPL void cvDestroyWindow( const char* name) {}
53 CV_IMPL void cvDestroyAllWindows( void ) {}
54 CV_IMPL void cvShowImage( const char* name, const CvArr* arr) {}
55 CV_IMPL void cvResizeWindow( const char* name, int width, int height) {}
56 CV_IMPL void cvMoveWindow( const char* name, int x, int y){}
57 CV_IMPL int cvCreateTrackbar (const char* trackbar_name,const char* window_name,
58 int* val, int count, CvTrackbarCallback on_notify) {return 0;}
59 CV_IMPL int cvCreateTrackbar2(const char* trackbar_name,const char* window_name,
60 int* val, int count, CvTrackbarCallback2 on_notify2, void* userdata) {return 0;}
61 CV_IMPL void cvSetMouseCallback( const char* name, CvMouseCallback function, void* info) {}
62 CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name ) {return 0;}
63 CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos) {}
64 CV_IMPL void* cvGetWindowHandle( const char* name ) {return NULL;}
65 CV_IMPL const char* cvGetWindowName( void* window_handle ) {return NULL;}
66 CV_IMPL int cvNamedWindow( const char* name, int flags ) {return 0; }
67 CV_IMPL int cvWaitKey (int maxWait) {return 0;}
68 //*** end IphoneOS Stubs ***/
71 #import <Cocoa/Cocoa.h>
76 const int TOP_BORDER = 7;
77 const int MIN_SLIDER_WIDTH=200;
79 static NSApplication *application = nil;
80 static NSAutoreleasePool *pool = nil;
81 static NSMutableDictionary *windows = nil;
82 static bool wasInitialized = false;
84 @interface CVView : NSView {
87 @property(retain) NSImage *image;
88 - (void)setImageData:(CvArr *)arr;
91 @interface CVSlider : NSView {
96 CvTrackbarCallback callback;
97 CvTrackbarCallback2 callback2;
99 @property(retain) NSSlider *slider;
100 @property(retain) NSTextField *name;
101 @property(assign) int *value;
102 @property(assign) void *userData;
103 @property(assign) CvTrackbarCallback callback;
104 @property(assign) CvTrackbarCallback2 callback2;
107 @interface CVWindow : NSWindow {
108 NSMutableDictionary *sliders;
109 CvMouseCallback mouseCallback;
115 @property(assign) CvMouseCallback mouseCallback;
116 @property(assign) void *mouseParam;
117 @property(assign) BOOL autosize;
118 @property(assign) BOOL firstContent;
119 @property(retain) NSMutableDictionary *sliders;
120 @property(readwrite) int status;
121 - (CVView *)contentView;
122 - (void)cvSendMouseEvent:(NSEvent *)event type:(int)type flags:(int)flags;
123 - (void)cvMouseEvent:(NSEvent *)event;
124 - (void)createSliderWithName:(const char *)name maxValue:(int)max value:(int *)value callback:(CvTrackbarCallback)callback;
127 /*static void icvCocoaCleanup(void)
129 //cout << "icvCocoaCleanup" << endl;
132 cvDestroyAllWindows();
133 //[application terminate:nil];
139 CV_IMPL int cvInitSystem( int , char** )
141 //cout << "cvInitSystem" << endl;
142 wasInitialized = true;
144 pool = [[NSAutoreleasePool alloc] init];
145 application = [NSApplication sharedApplication];
146 windows = [[NSMutableDictionary alloc] init];
148 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
150 #ifndef NSAppKitVersionNumber10_5
151 #define NSAppKitVersionNumber10_5 949
153 if( floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5 )
154 [application setActivationPolicy:0/*NSApplicationActivationPolicyRegular*/];
156 //[application finishLaunching];
157 //atexit(icvCocoaCleanup);
162 static CVWindow *cvGetWindow(const char *name) {
163 //cout << "cvGetWindow" << endl;
164 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
165 NSString *cvname = [NSString stringWithFormat:@"%s", name];
166 CVWindow* retval = (CVWindow*) [windows valueForKey:cvname] ;
167 //cout << "retain count: " << [retval retainCount] << endl;
168 //retval = [retval retain];
169 //cout << "retain count: " << [retval retainCount] << endl;
171 //cout << "retain count: " << [retval retainCount] << endl;
175 CV_IMPL int cvStartWindowThread()
177 //cout << "cvStartWindowThread" << endl;
181 CV_IMPL void cvDestroyWindow( const char* name)
184 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
185 //cout << "cvDestroyWindow" << endl;
186 CVWindow *window = cvGetWindow(name);
189 [windows removeObjectForKey:[NSString stringWithFormat:@"%s", name]];
195 CV_IMPL void cvDestroyAllWindows( void )
197 //cout << "cvDestroyAllWindows" << endl;
198 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
199 NSDictionary* list = [NSDictionary dictionaryWithDictionary:windows];
200 for(NSString *key in list) {
201 cvDestroyWindow([key cStringUsingEncoding:NSASCIIStringEncoding]);
207 CV_IMPL void cvShowImage( const char* name, const CvArr* arr)
209 //cout << "cvShowImage" << endl;
210 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
211 CVWindow *window = cvGetWindow(name);
214 cvNamedWindow(name, CV_WINDOW_AUTOSIZE);
215 window = cvGetWindow(name);
220 bool empty = [[window contentView] image] == nil;
221 NSRect rect = [window frame];
222 NSRect vrectOld = [[window contentView] frame];
224 [[window contentView] setImageData:(CvArr *)arr];
225 if([window autosize] || [window firstContent] || empty)
227 //Set new view size considering sliders (reserve height and min width)
228 NSRect vrectNew = vrectOld;
229 int slider_height = 0;
230 for(NSString *key in [window sliders]) {
231 slider_height += [[[window sliders] valueForKey:key] frame].size.height;
233 vrectNew.size.height = [[[window contentView] image] size].height + slider_height;
234 vrectNew.size.width = std::max<int>([[[window contentView] image] size].width, MIN_SLIDER_WIDTH);
235 [[window contentView] setFrameSize:vrectNew.size]; //adjust sliders to fit new window size
237 rect.size.width += vrectNew.size.width - vrectOld.size.width;
238 rect.size.height += vrectNew.size.height - vrectOld.size.height;
239 rect.origin.y -= vrectNew.size.height - vrectOld.size.height;
241 [window setFrame:rect display:YES];
245 [window setFirstContent:NO];
250 CV_IMPL void cvResizeWindow( const char* name, int width, int height)
253 //cout << "cvResizeWindow" << endl;
254 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
255 CVWindow *window = cvGetWindow(name);
257 NSRect frame = [window frame];
258 frame.size.width = width;
259 frame.size.height = height;
260 [window setFrame:frame display:YES];
265 CV_IMPL void cvMoveWindow( const char* name, int x, int y)
268 CV_FUNCNAME("cvMoveWindow");
271 NSAutoreleasePool* localpool1 = [[NSAutoreleasePool alloc] init];
272 CVWindow *window = nil;
275 CV_ERROR( CV_StsNullPtr, "NULL window name" );
276 //cout << "cvMoveWindow"<< endl;
277 window = cvGetWindow(name);
279 y = [[window screen] frame].size.height - y;
280 [window setFrameTopLeftPoint:NSMakePoint(x, y)];
287 CV_IMPL int cvCreateTrackbar (const char* trackbar_name,
288 const char* window_name,
290 CvTrackbarCallback on_notify)
292 CV_FUNCNAME("cvCreateTrackbar");
296 CVWindow *window = nil;
297 NSAutoreleasePool* localpool2 = nil;
300 if (localpool2 != nil) [localpool2 drain];
301 localpool2 = [[NSAutoreleasePool alloc] init];
303 if(window_name == NULL)
304 CV_ERROR( CV_StsNullPtr, "NULL window name" );
306 //cout << "cvCreateTrackbar" << endl ;
307 window = cvGetWindow(window_name);
309 [window createSliderWithName:trackbar_name
321 CV_IMPL int cvCreateTrackbar2(const char* trackbar_name,
322 const char* window_name,
324 CvTrackbarCallback2 on_notify2,
327 //cout <<"cvCreateTrackbar2" << endl;
328 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
329 int res = cvCreateTrackbar(trackbar_name, window_name, val, count, NULL);
331 CVSlider *slider = [[cvGetWindow(window_name) sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]];
332 [slider setCallback2:on_notify2];
333 [slider setUserData:userdata];
341 cvSetMouseCallback( const char* name, CvMouseCallback function, void* info)
343 CV_FUNCNAME("cvSetMouseCallback");
345 CVWindow *window = nil;
346 NSAutoreleasePool* localpool3 = nil;
348 //cout << "cvSetMouseCallback" << endl;
350 if (localpool3 != nil) [localpool3 drain];
351 localpool3 = [[NSAutoreleasePool alloc] init];
354 CV_ERROR( CV_StsNullPtr, "NULL window name" );
356 window = cvGetWindow(name);
358 [window setMouseCallback:function];
359 [window setMouseParam:info];
366 CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name )
368 CV_FUNCNAME("cvGetTrackbarPos");
370 CVWindow *window = nil;
372 NSAutoreleasePool* localpool4 = nil;
375 //cout << "cvGetTrackbarPos" << endl;
376 if(trackbar_name == NULL || window_name == NULL)
377 CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
379 if (localpool4 != nil) [localpool4 drain];
380 localpool4 = [[NSAutoreleasePool alloc] init];
382 window = cvGetWindow(window_name);
384 CVSlider *slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]];
386 pos = [[slider slider] intValue];
394 CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos)
396 CV_FUNCNAME("cvSetTrackbarPos");
398 CVWindow *window = nil;
399 CVSlider *slider = nil;
400 NSAutoreleasePool* localpool5 = nil;
403 //cout << "cvSetTrackbarPos" << endl;
404 if(trackbar_name == NULL || window_name == NULL)
405 CV_ERROR( CV_StsNullPtr, "NULL trackbar or window name" );
408 CV_ERROR( CV_StsOutOfRange, "Bad trackbar maximal value" );
410 if (localpool5 != nil) [localpool5 drain];
411 localpool5 = [[NSAutoreleasePool alloc] init];
413 window = cvGetWindow(window_name);
415 slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]];
417 [[slider slider] setIntValue:pos];
425 CV_IMPL void* cvGetWindowHandle( const char* name )
427 //cout << "cvGetWindowHandle" << endl;
428 return cvGetWindow(name);
432 CV_IMPL const char* cvGetWindowName( void* window_handle )
434 //cout << "cvGetWindowName" << endl;
435 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
436 for(NSString *key in windows) {
437 if([windows valueForKey:key] == window_handle) {
439 return [key UTF8String];
446 CV_IMPL int cvNamedWindow( const char* name, int flags )
448 if( !wasInitialized )
451 //cout << "cvNamedWindow" << endl;
452 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
453 CVWindow *window = cvGetWindow(name);
456 [window setAutosize:(flags == CV_WINDOW_AUTOSIZE)];
461 NSScreen* mainDisplay = [NSScreen mainScreen];
463 NSString *windowName = [NSString stringWithFormat:@"%s", name];
464 NSUInteger showResize = (flags == CV_WINDOW_AUTOSIZE) ? 0: NSResizableWindowMask ;
465 NSUInteger styleMask = NSTitledWindowMask|NSMiniaturizableWindowMask|showResize;
466 CGFloat windowWidth = [NSWindow minFrameWidthWithTitle:windowName styleMask:styleMask];
467 NSRect initContentRect = NSMakeRect(0, 0, windowWidth, 0);
469 NSRect dispFrame = [mainDisplay visibleFrame];
470 initContentRect.origin.y = dispFrame.size.height-20;
474 window = [[CVWindow alloc] initWithContentRect:initContentRect
475 styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|showResize
476 backing:NSBackingStoreBuffered
480 [window setFrameTopLeftPoint:initContentRect.origin];
482 [window setFirstContent:YES];
484 [window setContentView:[[CVView alloc] init]];
486 [window setHasShadow:YES];
487 [window setAcceptsMouseMovedEvents:YES];
488 [window useOptimizedDrawing:YES];
489 [window setTitle:windowName];
490 [window makeKeyAndOrderFront:nil];
492 [window setAutosize:(flags == CV_WINDOW_AUTOSIZE)];
494 [windows setValue:window forKey:windowName];
497 return [windows count]-1;
500 CV_IMPL int cvWaitKey (int maxWait)
502 //cout << "cvWaitKey" << endl;
504 NSAutoreleasePool *localpool = [[NSAutoreleasePool alloc] init];
505 double start = [[NSDate date] timeIntervalSince1970];
508 if(([[NSDate date] timeIntervalSince1970] - start) * 1000 >= maxWait && maxWait>0)
511 //event = [application currentEvent];
513 localpool = [[NSAutoreleasePool alloc] init];
517 nextEventMatchingMask:NSAnyEventMask
518 untilDate://[NSDate dateWithTimeIntervalSinceNow: 1./100]
520 inMode:NSDefaultRunLoopMode
523 if([event type] == NSKeyDown) {
524 returnCode = [[event characters] characterAtIndex:0];
528 [application sendEvent:event];
529 [application updateWindows];
531 [NSThread sleepForTimeInterval:1/100.];
538 double cvGetModeWindow_COCOA( const char* name )
541 CVWindow *window = nil;
543 CV_FUNCNAME( "cvGetModeWindow_COCOA" );
548 CV_ERROR( CV_StsNullPtr, "NULL name string" );
551 window = cvGetWindow( name );
552 if ( window == NULL )
554 CV_ERROR( CV_StsNullPtr, "NULL window" );
557 result = window.status;
563 void cvSetModeWindow_COCOA( const char* name, double prop_value )
565 CVWindow *window = nil;
566 NSDictionary *fullscreenOptions = nil;
567 NSAutoreleasePool* localpool = nil;
569 CV_FUNCNAME( "cvSetModeWindow_COCOA" );
574 CV_ERROR( CV_StsNullPtr, "NULL name string" );
577 window = cvGetWindow(name);
578 if ( window == NULL )
580 CV_ERROR( CV_StsNullPtr, "NULL window" );
583 if ( [window autosize] )
588 localpool = [[NSAutoreleasePool alloc] init];
590 fullscreenOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:NSFullScreenModeSetting];
591 if ( [[window contentView] isInFullScreenMode] && prop_value==CV_WINDOW_NORMAL )
593 [[window contentView] exitFullScreenModeWithOptions:fullscreenOptions];
594 window.status=CV_WINDOW_NORMAL;
596 else if( ![[window contentView] isInFullScreenMode] && prop_value==CV_WINDOW_FULLSCREEN )
598 [[window contentView] enterFullScreenMode:[NSScreen mainScreen] withOptions:fullscreenOptions];
599 window.status=CV_WINDOW_FULLSCREEN;
607 @implementation CVWindow
609 @synthesize mouseCallback;
610 @synthesize mouseParam;
611 @synthesize autosize;
612 @synthesize firstContent;
616 - (void)cvSendMouseEvent:(NSEvent *)event type:(int)type flags:(int)flags {
618 //cout << "cvSendMouseEvent" << endl;
619 NSPoint mp = [NSEvent mouseLocation];
620 //NSRect visible = [[self contentView] frame];
621 mp = [self convertScreenToBase: mp];
622 double viewHeight = [self contentView].frame.size.height;
623 double viewWidth = [self contentView].frame.size.width;
624 CVWindow *window = (CVWindow *)[[self contentView] window];
625 for(NSString *key in [window sliders]) {
626 NSSlider *slider = [[window sliders] valueForKey:key];
627 viewHeight = std::min(viewHeight, (double)([slider frame].origin.y));
629 viewHeight -= TOP_BORDER;
630 mp.y = viewHeight - mp.y;
632 NSImage* image = ((CVView*)[self contentView]).image;
633 NSSize imageSize = [image size];
634 mp.x = mp.x * imageSize.width / std::max(viewWidth, 1.);
635 mp.y = mp.y * imageSize.height / std::max(viewHeight, 1.);
637 if( mp.x >= 0 && mp.y >= 0 && mp.x < imageSize.width && mp.y < imageSize.height )
638 mouseCallback(type, mp.x, mp.y, flags, mouseParam);
641 - (void)cvMouseEvent:(NSEvent *)event {
642 //cout << "cvMouseEvent" << endl;
647 if([event modifierFlags] & NSShiftKeyMask) flags |= CV_EVENT_FLAG_SHIFTKEY;
648 if([event modifierFlags] & NSControlKeyMask) flags |= CV_EVENT_FLAG_CTRLKEY;
649 if([event modifierFlags] & NSAlternateKeyMask) flags |= CV_EVENT_FLAG_ALTKEY;
651 if([event type] == NSLeftMouseDown) {[self cvSendMouseEvent:event type:CV_EVENT_LBUTTONDOWN flags:flags | CV_EVENT_FLAG_LBUTTON];}
652 if([event type] == NSLeftMouseUp) {[self cvSendMouseEvent:event type:CV_EVENT_LBUTTONUP flags:flags | CV_EVENT_FLAG_LBUTTON];}
653 if([event type] == NSRightMouseDown){[self cvSendMouseEvent:event type:CV_EVENT_RBUTTONDOWN flags:flags | CV_EVENT_FLAG_RBUTTON];}
654 if([event type] == NSRightMouseUp) {[self cvSendMouseEvent:event type:CV_EVENT_RBUTTONUP flags:flags | CV_EVENT_FLAG_RBUTTON];}
655 if([event type] == NSOtherMouseDown){[self cvSendMouseEvent:event type:CV_EVENT_MBUTTONDOWN flags:flags];}
656 if([event type] == NSOtherMouseUp) {[self cvSendMouseEvent:event type:CV_EVENT_MBUTTONUP flags:flags];}
657 if([event type] == NSMouseMoved) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags];}
658 if([event type] == NSLeftMouseDragged) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags | CV_EVENT_FLAG_LBUTTON];}
659 if([event type] == NSRightMouseDragged) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags | CV_EVENT_FLAG_RBUTTON];}
660 if([event type] == NSOtherMouseDragged) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags | CV_EVENT_FLAG_MBUTTON];}
662 - (void)keyDown:(NSEvent *)theEvent {
663 //cout << "keyDown" << endl;
664 [super keyDown:theEvent];
666 - (void)rightMouseDragged:(NSEvent *)theEvent {
667 //cout << "rightMouseDragged" << endl ;
668 [self cvMouseEvent:theEvent];
670 - (void)rightMouseUp:(NSEvent *)theEvent {
671 //cout << "rightMouseUp" << endl;
672 [self cvMouseEvent:theEvent];
674 - (void)rightMouseDown:(NSEvent *)theEvent {
675 // Does not seem to work?
676 //cout << "rightMouseDown" << endl;
677 [self cvMouseEvent:theEvent];
679 - (void)mouseMoved:(NSEvent *)theEvent {
680 [self cvMouseEvent:theEvent];
682 - (void)otherMouseDragged:(NSEvent *)theEvent {
683 [self cvMouseEvent:theEvent];
685 - (void)otherMouseUp:(NSEvent *)theEvent {
686 [self cvMouseEvent:theEvent];
688 - (void)otherMouseDown:(NSEvent *)theEvent {
689 [self cvMouseEvent:theEvent];
691 - (void)mouseDragged:(NSEvent *)theEvent {
692 [self cvMouseEvent:theEvent];
694 - (void)mouseUp:(NSEvent *)theEvent {
695 [self cvMouseEvent:theEvent];
697 - (void)mouseDown:(NSEvent *)theEvent {
698 [self cvMouseEvent:theEvent];
701 - (void)createSliderWithName:(const char *)name maxValue:(int)max value:(int *)value callback:(CvTrackbarCallback)callback {
702 //cout << "createSliderWithName" << endl;
704 sliders = [[NSMutableDictionary alloc] init];
706 NSString *cvname = [NSString stringWithFormat:@"%s", name];
708 // Avoid overwriting slider
709 if([sliders valueForKey:cvname]!=nil)
713 CVSlider *slider = [[CVSlider alloc] init];
714 [[slider name] setStringValue:cvname];
715 [[slider slider] setMaxValue:max];
716 [[slider slider] setMinValue:0];
717 [[slider slider] setNumberOfTickMarks:(max+1)];
718 [[slider slider] setAllowsTickMarkValuesOnly:YES];
721 [[slider slider] setIntValue:*value];
722 [slider setValue:value];
725 [slider setCallback:callback];
728 [sliders setValue:slider forKey:cvname];
729 [[self contentView] addSubview:slider];
732 //update contentView size to contain sliders
733 NSSize viewSize=[[self contentView] frame].size,
734 sliderSize=[slider frame].size;
735 viewSize.height += sliderSize.height;
736 viewSize.width = std::max<int>(viewSize.width, MIN_SLIDER_WIDTH);
738 // Update slider sizes
739 [[self contentView] setFrameSize:viewSize];
740 [[self contentView] setNeedsDisplay:YES];
742 //update window size to contain sliders
743 NSRect rect = [self frame];
744 rect.size.height += [slider frame].size.height;
745 rect.size.width = std::max<int>(rect.size.width, MIN_SLIDER_WIDTH);
746 [self setFrame:rect display:YES];
752 - (CVView *)contentView {
753 return (CVView*)[super contentView];
758 @implementation CVView
763 //cout << "CVView init" << endl;
765 image = [[NSImage alloc] init];
769 - (void)setImageData:(CvArr *)arr {
770 //cout << "setImageData" << endl;
771 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
772 CvMat *arrMat, *cvimage, stub;
774 arrMat = cvGetMat(arr, &stub);
776 cvimage = cvCreateMat(arrMat->rows, arrMat->cols, CV_8UC3);
777 cvConvertImage(arrMat, cvimage, CV_CVTIMG_SWAP_RB);
779 /*CGColorSpaceRef colorspace = NULL;
780 CGDataProviderRef provider = NULL;
781 int width = cvimage->width;
782 int height = cvimage->height;
784 colorspace = CGColorSpaceCreateDeviceRGB();
789 provider = CGDataProviderCreateWithData(NULL, cvimage->data.ptr, width * height , NULL );
791 CGImageRef imageRef = CGImageCreate(width, height, size , size*nbChannels , cvimage->step, colorspace, kCGImageAlphaNone , provider, NULL, true, kCGRenderingIntentDefault);
793 NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCGImage:imageRef];
798 NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
799 pixelsWide:cvimage->width
800 pixelsHigh:cvimage->height
805 colorSpaceName:NSDeviceRGBColorSpace
806 bytesPerRow:(cvimage->width * 4)
809 int pixelCount = cvimage->width * cvimage->height;
810 unsigned char *src = cvimage->data.ptr;
811 unsigned char *dst = [bitmap bitmapData];
813 for( int i = 0; i < pixelCount; i++ )
815 dst[i * 4 + 0] = src[i * 3 + 0];
816 dst[i * 4 + 1] = src[i * 3 + 1];
817 dst[i * 4 + 2] = src[i * 3 + 2];
823 image = [[NSImage alloc] init];
824 [image addRepresentation:bitmap];
827 /*CGColorSpaceRelease(colorspace);
828 CGDataProviderRelease(provider);
829 CGImageRelease(imageRef);*/
830 cvReleaseMat(&cvimage);
833 [self setNeedsDisplay:YES];
837 - (void)setFrameSize:(NSSize)size {
838 //cout << "setFrameSize" << endl;
839 [super setFrameSize:size];
841 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
842 int height = size.height;
844 CVWindow *cvwindow = (CVWindow *)[self window];
845 for(NSString *key in [cvwindow sliders]) {
846 NSSlider *slider = [[cvwindow sliders] valueForKey:key];
847 NSRect r = [slider frame];
848 r.origin.y = height - r.size.height;
849 r.size.width = [[cvwindow contentView] frame].size.width;
851 height -= r.size.height;
856 - (void)drawRect:(NSRect)rect {
857 //cout << "drawRect" << endl;
858 [super drawRect:rect];
860 NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
861 CVWindow *cvwindow = (CVWindow *)[self window];
863 if ([cvwindow respondsToSelector:@selector(sliders)]) {
864 for(NSString *key in [cvwindow sliders]) {
865 height += [[[cvwindow sliders] valueForKey:key] frame].size.height;
870 NSRect imageRect = {{0,0}, {[image size].width, [image size].height}};
873 [image drawInRect: imageRect
875 operation: NSCompositeSourceOver
884 @implementation CVSlider
889 @synthesize userData;
890 @synthesize callback;
891 @synthesize callback2;
900 [self setFrame:NSMakeRect(0,0,200,30)];
902 name = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 0,110, 25)];
903 [name setEditable:NO];
904 [name setSelectable:NO];
905 [name setBezeled:NO];
906 [name setBordered:NO];
907 [name setDrawsBackground:NO];
908 [[name cell] setLineBreakMode:NSLineBreakByTruncatingTail];
909 [self addSubview:name];
911 slider = [[NSSlider alloc] initWithFrame:NSMakeRect(120, 0, 70, 25)];
912 [slider setAutoresizingMask:NSViewWidthSizable];
913 [slider setMinValue:0];
914 [slider setMaxValue:100];
915 [slider setContinuous:YES];
916 [slider setTarget:self];
917 [slider setAction:@selector(sliderChanged:)];
918 [self addSubview:slider];
920 [self setAutoresizingMask:NSViewWidthSizable];
922 //[self setFrame:NSMakeRect(12, 0, 100, 30)];
927 - (void)sliderChanged:(NSNotification *)notification {
929 int pos = [slider intValue];
935 callback2(pos, userData);