mirror of
https://github.com/opencv/opencv.git
synced 2024-12-12 15:19:11 +08:00
976 lines
30 KiB
Plaintext
976 lines
30 KiB
Plaintext
/* The file is the modified version of window_cocoa.mm from opencv-cocoa project by Andre Cohen */
|
|
|
|
/*M///////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
|
//
|
|
// By downloading, copying, installing or using the software you agree to this license.
|
|
// If you do not agree to this license, do not download, install,
|
|
// copy or use the software.
|
|
//
|
|
//
|
|
// License Agreement
|
|
// For Open Source Computer Vision Library
|
|
//
|
|
// Copyright (C) 2010, Willow Garage Inc., all rights reserved.
|
|
// Third party copyrights are property of their respective owners.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without modification,
|
|
// are permitted provided that the following conditions are met:
|
|
//
|
|
// * Redistribution's of source code must retain the above copyright notice,
|
|
// this list of conditions and the following disclaimer.
|
|
//
|
|
// * Redistribution's in binary form must reproduce the above copyright notice,
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
// and/or other materials provided with the distribution.
|
|
//
|
|
// * The name of Intel Corporation may not be used to endorse or promote products
|
|
// derived from this software without specific prior written permission.
|
|
//
|
|
// This software is provided by the copyright holders and contributors "as is" and
|
|
// any express or implied warranties, including, but not limited to, the implied
|
|
// warranties of merchantability and fitness for a particular purpose are disclaimed.
|
|
// In no event shall the Intel Corporation or contributors be liable for any direct,
|
|
// indirect, incidental, special, exemplary, or consequential damages
|
|
// (including, but not limited to, procurement of substitute goods or services;
|
|
// loss of use, data, or profits; or business interruption) however caused
|
|
// and on any theory of liability, whether in contract, strict liability,
|
|
// or tort (including negligence or otherwise) arising in any way out of
|
|
// the use of this software, even if advised of the possibility of such damage.
|
|
//
|
|
//M*/
|
|
#include "precomp.hpp"
|
|
|
|
#import <TargetConditionals.h>
|
|
|
|
#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 cvSetTrackbarMax(const char* trackbar_name, const char* window_name, int maxval) {}
|
|
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 <Cocoa/Cocoa.h>
|
|
|
|
#include <iostream>
|
|
using namespace std;
|
|
|
|
const int TOP_BORDER = 7;
|
|
const int MIN_SLIDER_WIDTH=200;
|
|
|
|
static NSApplication *application = nil;
|
|
static NSAutoreleasePool *pool = nil;
|
|
static NSMutableDictionary *windows = nil;
|
|
static bool wasInitialized = false;
|
|
|
|
@interface CVView : NSView {
|
|
NSImage *image;
|
|
}
|
|
@property(retain) NSImage *image;
|
|
- (void)setImageData:(CvArr *)arr;
|
|
@end
|
|
|
|
@interface CVSlider : NSView {
|
|
NSSlider *slider;
|
|
NSTextField *name;
|
|
int *value;
|
|
void *userData;
|
|
CvTrackbarCallback callback;
|
|
CvTrackbarCallback2 callback2;
|
|
}
|
|
@property(retain) NSSlider *slider;
|
|
@property(retain) NSTextField *name;
|
|
@property(assign) int *value;
|
|
@property(assign) void *userData;
|
|
@property(assign) CvTrackbarCallback callback;
|
|
@property(assign) CvTrackbarCallback2 callback2;
|
|
@end
|
|
|
|
@interface CVWindow : NSWindow {
|
|
NSMutableDictionary *sliders;
|
|
CvMouseCallback mouseCallback;
|
|
void *mouseParam;
|
|
BOOL autosize;
|
|
BOOL firstContent;
|
|
int status;
|
|
}
|
|
@property(assign) CvMouseCallback mouseCallback;
|
|
@property(assign) void *mouseParam;
|
|
@property(assign) BOOL autosize;
|
|
@property(assign) BOOL firstContent;
|
|
@property(retain) NSMutableDictionary *sliders;
|
|
@property(readwrite) int status;
|
|
- (CVView *)contentView;
|
|
- (void)cvSendMouseEvent:(NSEvent *)event type:(int)type flags:(int)flags;
|
|
- (void)cvMouseEvent:(NSEvent *)event;
|
|
- (void)createSliderWithName:(const char *)name maxValue:(int)max value:(int *)value callback:(CvTrackbarCallback)callback;
|
|
@end
|
|
|
|
/*static void icvCocoaCleanup(void)
|
|
{
|
|
//cout << "icvCocoaCleanup" << endl;
|
|
if( application )
|
|
{
|
|
cvDestroyAllWindows();
|
|
//[application terminate:nil];
|
|
application = 0;
|
|
[pool release];
|
|
}
|
|
}*/
|
|
|
|
CV_IMPL int cvInitSystem( int , char** )
|
|
{
|
|
//cout << "cvInitSystem" << endl;
|
|
wasInitialized = true;
|
|
|
|
pool = [[NSAutoreleasePool alloc] init];
|
|
application = [NSApplication sharedApplication];
|
|
windows = [[NSMutableDictionary alloc] init];
|
|
|
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
|
|
|
#ifndef NSAppKitVersionNumber10_5
|
|
#define NSAppKitVersionNumber10_5 949
|
|
#endif
|
|
if( floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_5 )
|
|
[application setActivationPolicy:NSApplicationActivationPolicyRegular];
|
|
#endif
|
|
//[application finishLaunching];
|
|
//atexit(icvCocoaCleanup);
|
|
|
|
setlocale(LC_NUMERIC,"C");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static CVWindow *cvGetWindow(const char *name) {
|
|
//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 close];
|
|
[windows removeObjectForKey:[NSString stringWithFormat:@"%s", name]];
|
|
}
|
|
[localpool drain];
|
|
}
|
|
|
|
|
|
CV_IMPL void cvDestroyAllWindows( void )
|
|
{
|
|
//cout << "cvDestroyAllWindows" << endl;
|
|
NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
|
|
NSDictionary* list = [NSDictionary dictionaryWithDictionary:windows];
|
|
for(NSString *key in list) {
|
|
cvDestroyWindow([key cStringUsingEncoding:NSASCIIStringEncoding]);
|
|
}
|
|
[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)
|
|
{
|
|
cvNamedWindow(name, CV_WINDOW_AUTOSIZE);
|
|
window = cvGetWindow(name);
|
|
}
|
|
|
|
if(window)
|
|
{
|
|
bool empty = [[window contentView] image] == nil;
|
|
NSRect rect = [window frame];
|
|
NSRect vrectOld = [[window contentView] frame];
|
|
|
|
[[window contentView] setImageData:(CvArr *)arr];
|
|
if([window autosize] || [window firstContent] || empty)
|
|
{
|
|
//Set new view size considering sliders (reserve height and min width)
|
|
NSRect vrectNew = vrectOld;
|
|
int slider_height = 0;
|
|
for(NSString *key in [window sliders]) {
|
|
slider_height += [[[window sliders] valueForKey:key] frame].size.height;
|
|
}
|
|
vrectNew.size.height = [[[window contentView] image] size].height + slider_height;
|
|
vrectNew.size.width = std::max<int>([[[window contentView] image] size].width, MIN_SLIDER_WIDTH);
|
|
[[window contentView] setFrameSize:vrectNew.size]; //adjust sliders to fit new window 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 && ![window autosize]) {
|
|
NSRect frame = [window frame];
|
|
frame.size.width = width;
|
|
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__;
|
|
}
|
|
|
|
CV_IMPL int cvCreateTrackbar (const char* trackbar_name,
|
|
const char* window_name,
|
|
int* val, int count,
|
|
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
|
|
maxValue:count
|
|
value:val
|
|
callback:on_notify];
|
|
result = 1;
|
|
}
|
|
[localpool2 drain];
|
|
__END__;
|
|
return result;
|
|
}
|
|
|
|
|
|
CV_IMPL int cvCreateTrackbar2(const char* trackbar_name,
|
|
const char* window_name,
|
|
int* val, int count,
|
|
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;
|
|
}
|
|
|
|
|
|
CV_IMPL void
|
|
cvSetMouseCallback( const char* name, CvMouseCallback function, void* info)
|
|
{
|
|
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" );
|
|
|
|
window = cvGetWindow(name);
|
|
if(window) {
|
|
[window setMouseCallback:function];
|
|
[window setMouseParam:info];
|
|
}
|
|
[localpool3 drain];
|
|
|
|
__END__;
|
|
}
|
|
|
|
CV_IMPL int cvGetTrackbarPos( const char* trackbar_name, const char* window_name )
|
|
{
|
|
CV_FUNCNAME("cvGetTrackbarPos");
|
|
|
|
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]];
|
|
if(slider) {
|
|
pos = [[slider slider] intValue];
|
|
}
|
|
}
|
|
[localpool4 drain];
|
|
__END__;
|
|
return pos;
|
|
}
|
|
|
|
CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name, int pos)
|
|
{
|
|
CV_FUNCNAME("cvSetTrackbarPos");
|
|
|
|
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]];
|
|
if(slider) {
|
|
[[slider slider] setIntValue:pos];
|
|
}
|
|
}
|
|
[localpool5 drain];
|
|
|
|
__END__;
|
|
}
|
|
|
|
CV_IMPL void cvSetTrackbarMax(const char* trackbar_name, const char* window_name, int maxval)
|
|
{
|
|
CV_FUNCNAME("cvSetTrackbarPos");
|
|
|
|
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 (localpool5 != nil) [localpool5 drain];
|
|
localpool5 = [[NSAutoreleasePool alloc] init];
|
|
|
|
window = cvGetWindow(window_name);
|
|
if(window) {
|
|
slider = [[window sliders] valueForKey:[NSString stringWithFormat:@"%s", trackbar_name]];
|
|
if(slider) {
|
|
if(maxval >= 0) {
|
|
[[slider slider] setMaxValue:maxval];
|
|
}
|
|
}
|
|
}
|
|
[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) {
|
|
[localpool drain];
|
|
return [key UTF8String];
|
|
}
|
|
}
|
|
[localpool drain];
|
|
return 0;
|
|
}
|
|
|
|
CV_IMPL int cvNamedWindow( const char* name, int flags )
|
|
{
|
|
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;
|
|
}
|
|
|
|
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];
|
|
[window setAcceptsMouseMovedEvents:YES];
|
|
[window useOptimizedDrawing:YES];
|
|
[window setTitle:windowName];
|
|
[window makeKeyAndOrderFront:nil];
|
|
|
|
[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;
|
|
NSAutoreleasePool *localpool = [[NSAutoreleasePool alloc] init];
|
|
double start = [[NSDate date] timeIntervalSince1970];
|
|
|
|
while(true) {
|
|
if(([[NSDate date] timeIntervalSince1970] - start) * 1000 >= maxWait && maxWait>0)
|
|
break;
|
|
|
|
//event = [application currentEvent];
|
|
[localpool drain];
|
|
localpool = [[NSAutoreleasePool alloc] init];
|
|
|
|
NSEvent *event =
|
|
[application
|
|
nextEventMatchingMask:NSAnyEventMask
|
|
untilDate://[NSDate dateWithTimeIntervalSinceNow: 1./100]
|
|
[NSDate distantPast]
|
|
inMode:NSDefaultRunLoopMode
|
|
dequeue:YES];
|
|
|
|
if([event type] == NSKeyDown) {
|
|
returnCode = [[event characters] characterAtIndex:0];
|
|
break;
|
|
}
|
|
|
|
[application sendEvent:event];
|
|
[application updateWindows];
|
|
|
|
[NSThread sleepForTimeInterval:1/100.];
|
|
}
|
|
[localpool drain];
|
|
|
|
return returnCode;
|
|
}
|
|
|
|
double cvGetModeWindow_COCOA( const char* name )
|
|
{
|
|
double result = -1;
|
|
CVWindow *window = nil;
|
|
|
|
CV_FUNCNAME( "cvGetModeWindow_COCOA" );
|
|
|
|
__BEGIN__;
|
|
if( name == NULL )
|
|
{
|
|
CV_ERROR( CV_StsNullPtr, "NULL name string" );
|
|
}
|
|
|
|
window = cvGetWindow( name );
|
|
if ( window == NULL )
|
|
{
|
|
CV_ERROR( CV_StsNullPtr, "NULL window" );
|
|
}
|
|
|
|
result = window.status;
|
|
|
|
__END__;
|
|
return result;
|
|
}
|
|
|
|
void cvSetModeWindow_COCOA( const char* name, double prop_value )
|
|
{
|
|
CVWindow *window = nil;
|
|
NSDictionary *fullscreenOptions = nil;
|
|
NSAutoreleasePool* localpool = nil;
|
|
|
|
CV_FUNCNAME( "cvSetModeWindow_COCOA" );
|
|
|
|
__BEGIN__;
|
|
if( name == NULL )
|
|
{
|
|
CV_ERROR( CV_StsNullPtr, "NULL name string" );
|
|
}
|
|
|
|
window = cvGetWindow(name);
|
|
if ( window == NULL )
|
|
{
|
|
CV_ERROR( CV_StsNullPtr, "NULL window" );
|
|
}
|
|
|
|
if ( [window autosize] )
|
|
{
|
|
return;
|
|
}
|
|
|
|
localpool = [[NSAutoreleasePool alloc] init];
|
|
|
|
fullscreenOptions = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:NSFullScreenModeSetting];
|
|
if ( [[window contentView] isInFullScreenMode] && prop_value==CV_WINDOW_NORMAL )
|
|
{
|
|
[[window contentView] exitFullScreenModeWithOptions:fullscreenOptions];
|
|
window.status=CV_WINDOW_NORMAL;
|
|
}
|
|
else if( ![[window contentView] isInFullScreenMode] && prop_value==CV_WINDOW_FULLSCREEN )
|
|
{
|
|
[[window contentView] enterFullScreenMode:[NSScreen mainScreen] withOptions:fullscreenOptions];
|
|
window.status=CV_WINDOW_FULLSCREEN;
|
|
}
|
|
|
|
[localpool drain];
|
|
|
|
__END__;
|
|
}
|
|
|
|
@implementation CVWindow
|
|
|
|
@synthesize mouseCallback;
|
|
@synthesize mouseParam;
|
|
@synthesize autosize;
|
|
@synthesize firstContent;
|
|
@synthesize sliders;
|
|
@synthesize status;
|
|
|
|
- (void)cvSendMouseEvent:(NSEvent *)event type:(int)type flags:(int)flags {
|
|
(void)event;
|
|
//cout << "cvSendMouseEvent" << endl;
|
|
NSPoint mp = [NSEvent mouseLocation];
|
|
//NSRect visible = [[self contentView] frame];
|
|
mp = [self convertScreenToBase: mp];
|
|
double viewHeight = [self contentView].frame.size.height;
|
|
double viewWidth = [self contentView].frame.size.width;
|
|
CVWindow *window = (CVWindow *)[[self contentView] window];
|
|
for(NSString *key in [window sliders]) {
|
|
NSSlider *slider = [[window sliders] valueForKey:key];
|
|
viewHeight = std::min(viewHeight, (double)([slider frame].origin.y));
|
|
}
|
|
viewHeight -= TOP_BORDER;
|
|
mp.y = viewHeight - mp.y;
|
|
|
|
NSImage* image = ((CVView*)[self contentView]).image;
|
|
NSSize imageSize = [image size];
|
|
mp.x = mp.x * imageSize.width / std::max(viewWidth, 1.);
|
|
mp.y = mp.y * imageSize.height / std::max(viewHeight, 1.);
|
|
|
|
if( mp.x >= 0 && mp.y >= 0 && mp.x < imageSize.width && mp.y < imageSize.height )
|
|
mouseCallback(type, mp.x, mp.y, flags, mouseParam);
|
|
}
|
|
|
|
- (void)cvMouseEvent:(NSEvent *)event {
|
|
//cout << "cvMouseEvent" << endl;
|
|
if(!mouseCallback)
|
|
return;
|
|
|
|
int flags = 0;
|
|
if([event modifierFlags] & NSShiftKeyMask) flags |= CV_EVENT_FLAG_SHIFTKEY;
|
|
if([event modifierFlags] & NSControlKeyMask) flags |= CV_EVENT_FLAG_CTRLKEY;
|
|
if([event modifierFlags] & NSAlternateKeyMask) flags |= CV_EVENT_FLAG_ALTKEY;
|
|
|
|
if([event type] == NSLeftMouseDown) {[self cvSendMouseEvent:event type:CV_EVENT_LBUTTONDOWN flags:flags | CV_EVENT_FLAG_LBUTTON];}
|
|
if([event type] == NSLeftMouseUp) {[self cvSendMouseEvent:event type:CV_EVENT_LBUTTONUP flags:flags | CV_EVENT_FLAG_LBUTTON];}
|
|
if([event type] == NSRightMouseDown){[self cvSendMouseEvent:event type:CV_EVENT_RBUTTONDOWN flags:flags | CV_EVENT_FLAG_RBUTTON];}
|
|
if([event type] == NSRightMouseUp) {[self cvSendMouseEvent:event type:CV_EVENT_RBUTTONUP flags:flags | CV_EVENT_FLAG_RBUTTON];}
|
|
if([event type] == NSOtherMouseDown){[self cvSendMouseEvent:event type:CV_EVENT_MBUTTONDOWN flags:flags];}
|
|
if([event type] == NSOtherMouseUp) {[self cvSendMouseEvent:event type:CV_EVENT_MBUTTONUP flags:flags];}
|
|
if([event type] == NSMouseMoved) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags];}
|
|
if([event type] == NSLeftMouseDragged) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags | CV_EVENT_FLAG_LBUTTON];}
|
|
if([event type] == NSRightMouseDragged) {[self cvSendMouseEvent:event type:CV_EVENT_MOUSEMOVE flags:flags | CV_EVENT_FLAG_RBUTTON];}
|
|
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 {
|
|
[self cvMouseEvent:theEvent];
|
|
}
|
|
- (void)otherMouseDragged:(NSEvent *)theEvent {
|
|
[self cvMouseEvent:theEvent];
|
|
}
|
|
- (void)otherMouseUp:(NSEvent *)theEvent {
|
|
[self cvMouseEvent:theEvent];
|
|
}
|
|
- (void)otherMouseDown:(NSEvent *)theEvent {
|
|
[self cvMouseEvent:theEvent];
|
|
}
|
|
- (void)mouseDragged:(NSEvent *)theEvent {
|
|
[self cvMouseEvent:theEvent];
|
|
}
|
|
- (void)mouseUp:(NSEvent *)theEvent {
|
|
[self cvMouseEvent:theEvent];
|
|
}
|
|
- (void)mouseDown:(NSEvent *)theEvent {
|
|
[self cvMouseEvent:theEvent];
|
|
}
|
|
|
|
- (void)createSliderWithName:(const char *)name maxValue:(int)max value:(int *)value callback:(CvTrackbarCallback)callback {
|
|
//cout << "createSliderWithName" << endl;
|
|
if(sliders == nil)
|
|
sliders = [[NSMutableDictionary alloc] init];
|
|
|
|
NSString *cvname = [NSString stringWithFormat:@"%s", name];
|
|
|
|
// Avoid overwriting slider
|
|
if([sliders valueForKey:cvname]!=nil)
|
|
return;
|
|
|
|
// Create slider
|
|
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];
|
|
[slider setValue:value];
|
|
}
|
|
if(callback)
|
|
[slider setCallback:callback];
|
|
|
|
// Save slider
|
|
[sliders setValue:slider forKey:cvname];
|
|
[[self contentView] addSubview:slider];
|
|
|
|
|
|
//update contentView size to contain sliders
|
|
NSSize viewSize=[[self contentView] frame].size,
|
|
sliderSize=[slider frame].size;
|
|
viewSize.height += sliderSize.height;
|
|
viewSize.width = std::max<int>(viewSize.width, MIN_SLIDER_WIDTH);
|
|
|
|
// Update slider sizes
|
|
[[self contentView] setFrameSize:viewSize];
|
|
[[self contentView] setNeedsDisplay:YES];
|
|
|
|
//update window size to contain sliders
|
|
NSRect rect = [self frame];
|
|
rect.size.height += [slider frame].size.height;
|
|
rect.size.width = std::max<int>(rect.size.width, MIN_SLIDER_WIDTH);
|
|
[self setFrame:rect display:YES];
|
|
|
|
|
|
|
|
}
|
|
|
|
- (CVView *)contentView {
|
|
return (CVView*)[super contentView];
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation CVView
|
|
|
|
@synthesize image;
|
|
|
|
- (id)init {
|
|
//cout << "CVView init" << endl;
|
|
[super init];
|
|
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);
|
|
|
|
cvimage = cvCreateMat(arrMat->rows, arrMat->cols, CV_8UC3);
|
|
cvConvertImage(arrMat, cvimage, CV_CVTIMG_SWAP_RB);
|
|
|
|
/*CGColorSpaceRef colorspace = NULL;
|
|
CGDataProviderRef provider = NULL;
|
|
int width = cvimage->width;
|
|
int height = cvimage->height;
|
|
|
|
colorspace = CGColorSpaceCreateDeviceRGB();
|
|
|
|
int size = 8;
|
|
int nbChannels = 3;
|
|
|
|
provider = CGDataProviderCreateWithData(NULL, cvimage->data.ptr, width * height , NULL );
|
|
|
|
CGImageRef imageRef = CGImageCreate(width, height, size , size*nbChannels , cvimage->step, colorspace, kCGImageAlphaNone , provider, NULL, true, kCGRenderingIntentDefault);
|
|
|
|
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithCGImage:imageRef];
|
|
if(image) {
|
|
[image release];
|
|
}*/
|
|
|
|
NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
|
pixelsWide:cvimage->width
|
|
pixelsHigh:cvimage->height
|
|
bitsPerSample:8
|
|
samplesPerPixel:3
|
|
hasAlpha:NO
|
|
isPlanar:NO
|
|
colorSpaceName:NSDeviceRGBColorSpace
|
|
bytesPerRow:(cvimage->width * 4)
|
|
bitsPerPixel:32];
|
|
|
|
int pixelCount = cvimage->width * cvimage->height;
|
|
unsigned char *src = cvimage->data.ptr;
|
|
unsigned char *dst = [bitmap bitmapData];
|
|
|
|
for( int i = 0; i < pixelCount; i++ )
|
|
{
|
|
dst[i * 4 + 0] = src[i * 3 + 0];
|
|
dst[i * 4 + 1] = src[i * 3 + 1];
|
|
dst[i * 4 + 2] = src[i * 3 + 2];
|
|
}
|
|
|
|
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 *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;
|
|
r.size.width = [[cvwindow contentView] frame].size.width;
|
|
[slider setFrame:r];
|
|
height -= r.size.height;
|
|
}
|
|
[localpool drain];
|
|
}
|
|
|
|
- (void)drawRect:(NSRect)rect {
|
|
//cout << "drawRect" << endl;
|
|
[super drawRect:rect];
|
|
|
|
NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
|
|
CVWindow *cvwindow = (CVWindow *)[self window];
|
|
int height = 0;
|
|
if ([cvwindow respondsToSelector:@selector(sliders)]) {
|
|
for(NSString *key in [cvwindow sliders]) {
|
|
height += [[[cvwindow sliders] valueForKey:key] frame].size.height;
|
|
}
|
|
}
|
|
|
|
|
|
NSRect imageRect = {{0,0}, {[image size].width, [image size].height}};
|
|
|
|
if(image != nil) {
|
|
[image drawInRect: imageRect
|
|
fromRect: NSZeroRect
|
|
operation: NSCompositeSourceOver
|
|
fraction: 1.0];
|
|
}
|
|
[localpool release];
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation CVSlider
|
|
|
|
@synthesize slider;
|
|
@synthesize name;
|
|
@synthesize value;
|
|
@synthesize userData;
|
|
@synthesize callback;
|
|
@synthesize callback2;
|
|
|
|
- (id)init {
|
|
[super init];
|
|
|
|
callback = NULL;
|
|
value = NULL;
|
|
userData = NULL;
|
|
|
|
[self setFrame:NSMakeRect(0,0,200,30)];
|
|
|
|
name = [[NSTextField alloc] initWithFrame:NSMakeRect(10, 0,110, 25)];
|
|
[name setEditable:NO];
|
|
[name setSelectable:NO];
|
|
[name setBezeled:NO];
|
|
[name setBordered:NO];
|
|
[name setDrawsBackground:NO];
|
|
[[name cell] setLineBreakMode:NSLineBreakByTruncatingTail];
|
|
[self addSubview:name];
|
|
|
|
slider = [[NSSlider alloc] initWithFrame:NSMakeRect(120, 0, 70, 25)];
|
|
[slider setAutoresizingMask:NSViewWidthSizable];
|
|
[slider setMinValue:0];
|
|
[slider setMaxValue:100];
|
|
[slider setContinuous:YES];
|
|
[slider setTarget:self];
|
|
[slider setAction:@selector(sliderChanged:)];
|
|
[self addSubview:slider];
|
|
|
|
[self setAutoresizingMask:NSViewWidthSizable];
|
|
|
|
//[self setFrame:NSMakeRect(12, 0, 100, 30)];
|
|
|
|
return self;
|
|
}
|
|
|
|
- (void)sliderChanged:(NSNotification *)notification {
|
|
(void)notification;
|
|
int pos = [slider intValue];
|
|
if(value)
|
|
*value = pos;
|
|
if(callback)
|
|
callback(pos);
|
|
if(callback2)
|
|
callback2(pos, userData);
|
|
}
|
|
|
|
@end
|
|
|
|
#endif
|
|
|
|
/* End of file. */
|