Changeset View
Changeset View
Standalone View
Standalone View
intern/ghost/intern/GHOST_WindowCocoa.mm
| Show First 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
| - (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa; | - (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa; | ||||
| - (void)windowDidBecomeKey:(NSNotification *)notification; | - (void)windowDidBecomeKey:(NSNotification *)notification; | ||||
| - (void)windowDidResignKey:(NSNotification *)notification; | - (void)windowDidResignKey:(NSNotification *)notification; | ||||
| - (void)windowDidExpose:(NSNotification *)notification; | - (void)windowDidExpose:(NSNotification *)notification; | ||||
| - (void)windowDidResize:(NSNotification *)notification; | - (void)windowDidResize:(NSNotification *)notification; | ||||
| - (void)windowDidMove:(NSNotification *)notification; | - (void)windowDidMove:(NSNotification *)notification; | ||||
| - (void)windowWillMove:(NSNotification *)notification; | - (void)windowWillMove:(NSNotification *)notification; | ||||
| - (BOOL)windowShouldClose:(id)sender; | - (BOOL)windowShouldClose:(id)sender; | ||||
| - (void)windowDidChangeBackingProperties:(NSNotification *)notification; | - (void)windowDidChangeBackingProperties:(NSNotification *)notification; | ||||
| @end | @end | ||||
| @implementation CocoaWindowDelegate : NSObject | @implementation CocoaWindowDelegate : NSObject | ||||
| - (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa | - (void)setSystemAndWindowCocoa:(GHOST_SystemCocoa *)sysCocoa windowCocoa:(GHOST_WindowCocoa *)winCocoa | ||||
| { | { | ||||
| systemCocoa = sysCocoa; | systemCocoa = sysCocoa; | ||||
| associatedWindow = winCocoa; | associatedWindow = winCocoa; | ||||
| ▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | -(BOOL)canBecomeKeyWindow | ||||
| return YES; | return YES; | ||||
| } | } | ||||
| //The drag'n'drop dragging destination methods | //The drag'n'drop dragging destination methods | ||||
| - (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender | - (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender | ||||
| { | { | ||||
| NSPoint mouseLocation = [sender draggingLocation]; | NSPoint mouseLocation = [sender draggingLocation]; | ||||
| NSPasteboard *draggingPBoard = [sender draggingPasteboard]; | NSPasteboard *draggingPBoard = [sender draggingPasteboard]; | ||||
| if ([[draggingPBoard types] containsObject:NSTIFFPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeBitmap; | if ([[draggingPBoard types] containsObject:NSTIFFPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeBitmap; | ||||
| else if ([[draggingPBoard types] containsObject:NSFilenamesPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeFilenames; | else if ([[draggingPBoard types] containsObject:NSFilenamesPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeFilenames; | ||||
| else if ([[draggingPBoard types] containsObject:NSStringPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeString; | else if ([[draggingPBoard types] containsObject:NSStringPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeString; | ||||
| else return NSDragOperationNone; | else return NSDragOperationNone; | ||||
| associatedWindow->setAcceptDragOperation(TRUE); //Drag operation is accepted by default | associatedWindow->setAcceptDragOperation(TRUE); //Drag operation is accepted by default | ||||
| systemCocoa->handleDraggingEvent(GHOST_kEventDraggingEntered, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil); | systemCocoa->handleDraggingEvent(GHOST_kEventDraggingEntered, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil); | ||||
| return NSDragOperationCopy; | return NSDragOperationCopy; | ||||
| } | } | ||||
| - (BOOL)wantsPeriodicDraggingUpdates | - (BOOL)wantsPeriodicDraggingUpdates | ||||
| { | { | ||||
| return NO; //No need to overflow blender event queue. Events shall be sent only on changes | return NO; //No need to overflow blender event queue. Events shall be sent only on changes | ||||
| } | } | ||||
| - (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender | - (NSDragOperation)draggingUpdated:(id < NSDraggingInfo >)sender | ||||
| { | { | ||||
| NSPoint mouseLocation = [sender draggingLocation]; | NSPoint mouseLocation = [sender draggingLocation]; | ||||
| systemCocoa->handleDraggingEvent(GHOST_kEventDraggingUpdated, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil); | systemCocoa->handleDraggingEvent(GHOST_kEventDraggingUpdated, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil); | ||||
| return associatedWindow->canAcceptDragOperation() ? NSDragOperationCopy : NSDragOperationNone; | return associatedWindow->canAcceptDragOperation() ? NSDragOperationCopy : NSDragOperationNone; | ||||
| } | } | ||||
| - (void)draggingExited:(id < NSDraggingInfo >)sender | - (void)draggingExited:(id < NSDraggingInfo >)sender | ||||
| { | { | ||||
| systemCocoa->handleDraggingEvent(GHOST_kEventDraggingExited, m_draggedObjectType, associatedWindow, 0, 0, nil); | systemCocoa->handleDraggingEvent(GHOST_kEventDraggingExited, m_draggedObjectType, associatedWindow, 0, 0, nil); | ||||
| m_draggedObjectType = GHOST_kDragnDropTypeUnknown; | m_draggedObjectType = GHOST_kDragnDropTypeUnknown; | ||||
| } | } | ||||
| - (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender | - (BOOL)prepareForDragOperation:(id < NSDraggingInfo >)sender | ||||
| { | { | ||||
| if (associatedWindow->canAcceptDragOperation()) | if (associatedWindow->canAcceptDragOperation()) | ||||
| return YES; | return YES; | ||||
| else | else | ||||
| return NO; | return NO; | ||||
| } | } | ||||
| - (BOOL)performDragOperation:(id < NSDraggingInfo >)sender | - (BOOL)performDragOperation:(id < NSDraggingInfo >)sender | ||||
| { | { | ||||
| NSPoint mouseLocation = [sender draggingLocation]; | NSPoint mouseLocation = [sender draggingLocation]; | ||||
| NSPasteboard *draggingPBoard = [sender draggingPasteboard]; | NSPasteboard *draggingPBoard = [sender draggingPasteboard]; | ||||
| NSImage *droppedImg; | NSImage *droppedImg; | ||||
| id data; | id data; | ||||
| switch (m_draggedObjectType) { | switch (m_draggedObjectType) { | ||||
| case GHOST_kDragnDropTypeBitmap: | case GHOST_kDragnDropTypeBitmap: | ||||
| if ([NSImage canInitWithPasteboard:draggingPBoard]) { | if ([NSImage canInitWithPasteboard:draggingPBoard]) { | ||||
| droppedImg = [[NSImage alloc]initWithPasteboard:draggingPBoard]; | droppedImg = [[NSImage alloc]initWithPasteboard:draggingPBoard]; | ||||
| data = droppedImg; //[draggingPBoard dataForType:NSTIFFPboardType]; | data = droppedImg; //[draggingPBoard dataForType:NSTIFFPboardType]; | ||||
| } | } | ||||
| else return NO; | else return NO; | ||||
| break; | break; | ||||
| ▲ Show 20 Lines • Show All 286 Lines • ▼ Show 20 Lines | ) : | ||||
| m_customCursor(0), | m_customCursor(0), | ||||
| m_debug_context(is_debug) | m_debug_context(is_debug) | ||||
| { | { | ||||
| m_systemCocoa = systemCocoa; | m_systemCocoa = systemCocoa; | ||||
| m_fullScreen = false; | m_fullScreen = false; | ||||
| m_immediateDraw = false; | m_immediateDraw = false; | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| //Creates the window | //Creates the window | ||||
| NSRect rect; | NSRect rect; | ||||
| NSSize minSize; | NSSize minSize; | ||||
| rect.origin.x = left; | rect.origin.x = left; | ||||
| rect.origin.y = bottom; | rect.origin.y = bottom; | ||||
| rect.size.width = width; | rect.size.width = width; | ||||
| rect.size.height = height; | rect.size.height = height; | ||||
| m_window = [[CocoaWindow alloc] initWithContentRect:rect | m_window = [[CocoaWindow alloc] initWithContentRect:rect | ||||
| styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask | styleMask:NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask | NSMiniaturizableWindowMask | ||||
| backing:NSBackingStoreBuffered defer:NO]; | backing:NSBackingStoreBuffered defer:NO]; | ||||
| if (m_window == nil) { | if (m_window == nil) { | ||||
| [pool drain]; | [pool drain]; | ||||
| return; | return; | ||||
| } | } | ||||
| [m_window setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; | [m_window setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; | ||||
| //Forbid to resize the window below the blender defined minimum one | //Forbid to resize the window below the blender defined minimum one | ||||
| minSize.width = 320; | minSize.width = 320; | ||||
| minSize.height = 240; | minSize.height = 240; | ||||
| [m_window setContentMinSize:minSize]; | [m_window setContentMinSize:minSize]; | ||||
| //Creates the OpenGL View inside the window | //Creates the OpenGL View inside the window | ||||
| m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect]; | m_openGLView = [[CocoaOpenGLView alloc] initWithFrame:rect]; | ||||
| if (m_systemCocoa->m_nativePixel) { | if (m_systemCocoa->m_nativePixel) { | ||||
| // Needs to happen early when building with the 10.14 SDK, otherwise | // Needs to happen early when building with the 10.14 SDK, otherwise | ||||
| // has no effect until resizeing the window. | // has no effect until resizeing the window. | ||||
| if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { | if ([m_openGLView respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)]) { | ||||
| [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; | [m_openGLView setWantsBestResolutionOpenGLSurface:YES]; | ||||
| } | } | ||||
| } | } | ||||
| [m_openGLView setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; | [m_openGLView setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; | ||||
| [m_window setContentView:m_openGLView]; | [m_window setContentView:m_openGLView]; | ||||
| [m_window setInitialFirstResponder:m_openGLView]; | [m_window setInitialFirstResponder:m_openGLView]; | ||||
| [m_window makeKeyAndOrderFront:nil]; | [m_window makeKeyAndOrderFront:nil]; | ||||
| setDrawingContextType(type); | setDrawingContextType(type); | ||||
| updateDrawingContext(); | updateDrawingContext(); | ||||
| activateDrawingContext(); | activateDrawingContext(); | ||||
| setTitle(title); | setTitle(title); | ||||
| m_tablet.Active = GHOST_kTabletModeNone; | m_tablet.Active = GHOST_kTabletModeNone; | ||||
| CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init]; | CocoaWindowDelegate *windowDelegate = [[CocoaWindowDelegate alloc] init]; | ||||
| [windowDelegate setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; | [windowDelegate setSystemAndWindowCocoa:systemCocoa windowCocoa:this]; | ||||
| [m_window setDelegate:windowDelegate]; | [m_window setDelegate:windowDelegate]; | ||||
| [m_window setAcceptsMouseMovedEvents:YES]; | [m_window setAcceptsMouseMovedEvents:YES]; | ||||
| NSView *view = [m_window contentView]; | NSView *view = [m_window contentView]; | ||||
| [view setAcceptsTouchEvents:YES]; | [view setAcceptsTouchEvents:YES]; | ||||
| [m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, | [m_window registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, | ||||
| NSStringPboardType, NSTIFFPboardType, nil]]; | NSStringPboardType, NSTIFFPboardType, nil]]; | ||||
| if (state != GHOST_kWindowStateFullScreen) { | if (state != GHOST_kWindowStateFullScreen) { | ||||
| [m_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; | [m_window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; | ||||
| } | } | ||||
| if (state == GHOST_kWindowStateFullScreen) | if (state == GHOST_kWindowStateFullScreen) | ||||
| setState(GHOST_kWindowStateFullScreen); | setState(GHOST_kWindowStateFullScreen); | ||||
| setNativePixelSize(); | setNativePixelSize(); | ||||
| [pool drain]; | [pool drain]; | ||||
| } | } | ||||
| GHOST_WindowCocoa::~GHOST_WindowCocoa() | GHOST_WindowCocoa::~GHOST_WindowCocoa() | ||||
| { | { | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| if (m_customCursor) { | if (m_customCursor) { | ||||
| [m_customCursor release]; | [m_customCursor release]; | ||||
| m_customCursor = nil; | m_customCursor = nil; | ||||
| } | } | ||||
| releaseNativeHandles(); | releaseNativeHandles(); | ||||
| [m_openGLView release]; | [m_openGLView release]; | ||||
| if (m_window) { | if (m_window) { | ||||
| [m_window close]; | [m_window close]; | ||||
| } | } | ||||
| // Check for other blender opened windows and make the frontmost key | // Check for other blender opened windows and make the frontmost key | ||||
| // Note: for some reason the closed window is still in the list | // Note: for some reason the closed window is still in the list | ||||
| NSArray *windowsList = [NSApp orderedWindows]; | NSArray *windowsList = [NSApp orderedWindows]; | ||||
| for (int a = 0; a < [windowsList count]; a++) { | for (int a = 0; a < [windowsList count]; a++) { | ||||
| if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) { | if (m_window != (CocoaWindow *)[windowsList objectAtIndex:a]) { | ||||
| [[windowsList objectAtIndex:a] makeKeyWindow]; | [[windowsList objectAtIndex:a] makeKeyWindow]; | ||||
| break; | break; | ||||
| } | } | ||||
| Show All 16 Lines | |||||
| } | } | ||||
| void GHOST_WindowCocoa::setTitle(const STR_String& title) | void GHOST_WindowCocoa::setTitle(const STR_String& title) | ||||
| { | { | ||||
| GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid"); | GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid"); | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| NSString *windowTitle = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding]; | NSString *windowTitle = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding]; | ||||
| //Set associated file if applicable | //Set associated file if applicable | ||||
| if (windowTitle && [windowTitle hasPrefix:@"Blender"]) { | if (windowTitle && [windowTitle hasPrefix:@"Blender"]) { | ||||
| NSRange fileStrRange; | NSRange fileStrRange; | ||||
| NSString *associatedFileName; | NSString *associatedFileName; | ||||
| int len; | int len; | ||||
| fileStrRange.location = [windowTitle rangeOfString:@"["].location+1; | fileStrRange.location = [windowTitle rangeOfString:@"["].location+1; | ||||
| len = [windowTitle rangeOfString:@"]"].location - fileStrRange.location; | len = [windowTitle rangeOfString:@"]"].location - fileStrRange.location; | ||||
| if (len > 0) { | if (len > 0) { | ||||
| fileStrRange.length = len; | fileStrRange.length = len; | ||||
| associatedFileName = [windowTitle substringWithRange:fileStrRange]; | associatedFileName = [windowTitle substringWithRange:fileStrRange]; | ||||
| [m_window setTitle:[associatedFileName lastPathComponent]]; | [m_window setTitle:[associatedFileName lastPathComponent]]; | ||||
| //Blender used file open/save functions converte file names into legal URL ones | //Blender used file open/save functions converte file names into legal URL ones | ||||
| associatedFileName = [associatedFileName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; | associatedFileName = [associatedFileName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; | ||||
| @try { | @try { | ||||
| Show All 9 Lines | if (windowTitle && [windowTitle hasPrefix:@"Blender"]) { | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| [m_window setTitle:windowTitle]; | [m_window setTitle:windowTitle]; | ||||
| [m_window setRepresentedFilename:@""]; | [m_window setRepresentedFilename:@""]; | ||||
| } | } | ||||
| [windowTitle release]; | [windowTitle release]; | ||||
| [pool drain]; | [pool drain]; | ||||
| } | } | ||||
| void GHOST_WindowCocoa::getTitle(STR_String& title) const | void GHOST_WindowCocoa::getTitle(STR_String& title) const | ||||
| { | { | ||||
| GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid"); | GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid"); | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| NSString *windowTitle = [m_window title]; | NSString *windowTitle = [m_window title]; | ||||
| if (windowTitle != nil) { | if (windowTitle != nil) { | ||||
| title = [windowTitle UTF8String]; | title = [windowTitle UTF8String]; | ||||
| } | } | ||||
| [pool drain]; | [pool drain]; | ||||
| } | } | ||||
| void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const | void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const | ||||
| { | { | ||||
| NSRect rect; | NSRect rect; | ||||
| GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid"); | GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid"); | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| NSRect screenSize = [[m_window screen] visibleFrame]; | NSRect screenSize = [[m_window screen] visibleFrame]; | ||||
| rect = [m_window frame]; | rect = [m_window frame]; | ||||
| bounds.m_b = screenSize.size.height - (rect.origin.y -screenSize.origin.y); | bounds.m_b = screenSize.size.height - (rect.origin.y -screenSize.origin.y); | ||||
| bounds.m_l = rect.origin.x -screenSize.origin.x; | bounds.m_l = rect.origin.x -screenSize.origin.x; | ||||
| bounds.m_r = rect.origin.x-screenSize.origin.x + rect.size.width; | bounds.m_r = rect.origin.x-screenSize.origin.x + rect.size.width; | ||||
| bounds.m_t = screenSize.size.height - (rect.origin.y + rect.size.height -screenSize.origin.y); | bounds.m_t = screenSize.size.height - (rect.origin.y + rect.size.height -screenSize.origin.y); | ||||
| [pool drain]; | [pool drain]; | ||||
| } | } | ||||
| void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const | void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const | ||||
| { | { | ||||
| NSRect rect; | NSRect rect; | ||||
| GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid"); | GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid"); | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| NSRect screenSize = [[m_window screen] visibleFrame]; | NSRect screenSize = [[m_window screen] visibleFrame]; | ||||
| //Max window contents as screen size (excluding title bar...) | //Max window contents as screen size (excluding title bar...) | ||||
| NSRect contentRect = [CocoaWindow contentRectForFrameRect:screenSize | NSRect contentRect = [CocoaWindow contentRectForFrameRect:screenSize | ||||
| styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)]; | styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask)]; | ||||
| rect = [m_window contentRectForFrameRect:[m_window frame]]; | rect = [m_window contentRectForFrameRect:[m_window frame]]; | ||||
| bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y); | bounds.m_b = contentRect.size.height - (rect.origin.y -contentRect.origin.y); | ||||
| bounds.m_l = rect.origin.x -contentRect.origin.x; | bounds.m_l = rect.origin.x -contentRect.origin.x; | ||||
| bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width; | bounds.m_r = rect.origin.x-contentRect.origin.x + rect.size.width; | ||||
| bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y); | bounds.m_t = contentRect.size.height - (rect.origin.y + rect.size.height -contentRect.origin.y); | ||||
| [pool drain]; | [pool drain]; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const | ||||
| clientToScreenIntern(inX, inY, outX, outY); | clientToScreenIntern(inX, inY, outX, outY); | ||||
| } | } | ||||
| void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const | void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const | ||||
| { | { | ||||
| NSRect screenCoord; | NSRect screenCoord; | ||||
| NSRect baseCoord; | NSRect baseCoord; | ||||
| screenCoord.origin.x = inX; | screenCoord.origin.x = inX; | ||||
| screenCoord.origin.y = inY; | screenCoord.origin.y = inY; | ||||
| baseCoord = [m_window convertRectFromScreen:screenCoord]; | baseCoord = [m_window convertRectFromScreen:screenCoord]; | ||||
| outX = baseCoord.origin.x; | outX = baseCoord.origin.x; | ||||
| outY = baseCoord.origin.y; | outY = baseCoord.origin.y; | ||||
| } | } | ||||
| void GHOST_WindowCocoa::clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const | void GHOST_WindowCocoa::clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const | ||||
| { | { | ||||
| NSRect screenCoord; | NSRect screenCoord; | ||||
| NSRect baseCoord; | NSRect baseCoord; | ||||
| baseCoord.origin.x = inX; | baseCoord.origin.x = inX; | ||||
| baseCoord.origin.y = inY; | baseCoord.origin.y = inY; | ||||
| screenCoord = [m_window convertRectToScreen:baseCoord]; | screenCoord = [m_window convertRectToScreen:baseCoord]; | ||||
| outX = screenCoord.origin.x; | outX = screenCoord.origin.x; | ||||
| outY = screenCoord.origin.y; | outY = screenCoord.origin.y; | ||||
| } | } | ||||
| NSScreen* GHOST_WindowCocoa::getScreen() | NSScreen* GHOST_WindowCocoa::getScreen() | ||||
| { | { | ||||
| return [m_window screen]; | return [m_window screen]; | ||||
| } | } | ||||
| /* called for event, when window leaves monitor to another */ | /* called for event, when window leaves monitor to another */ | ||||
| void GHOST_WindowCocoa::setNativePixelSize(void) | void GHOST_WindowCocoa::setNativePixelSize(void) | ||||
| { | { | ||||
| NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; | NSRect backingBounds = [m_openGLView convertRectToBacking:[m_openGLView bounds]]; | ||||
| GHOST_Rect rect; | GHOST_Rect rect; | ||||
| getClientBounds(rect); | getClientBounds(rect); | ||||
| m_nativePixelSize = (float)backingBounds.size.width / (float)rect.getWidth(); | m_nativePixelSize = (float)backingBounds.size.width / (float)rect.getWidth(); | ||||
| } | } | ||||
| /** | /** | ||||
| * \note Fullscreen switch is not actual fullscreen with display capture. | * \note Fullscreen switch is not actual fullscreen with display capture. | ||||
| * As this capture removes all OS X window manager features. | * As this capture removes all OS X window manager features. | ||||
| * | * | ||||
| * Instead, the menu bar and the dock are hidden, and the window is made borderless and enlarged. | * Instead, the menu bar and the dock are hidden, and the window is made borderless and enlarged. | ||||
| * Thus, process switch, exposé, spaces, ... still work in fullscreen mode | * Thus, process switch, exposé, spaces, ... still work in fullscreen mode | ||||
| */ | */ | ||||
| GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) | GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) | ||||
| { | { | ||||
| GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid"); | GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid"); | ||||
| switch (state) { | switch (state) { | ||||
| case GHOST_kWindowStateMinimized: | case GHOST_kWindowStateMinimized: | ||||
| [m_window miniaturize:nil]; | [m_window miniaturize:nil]; | ||||
| break; | break; | ||||
| case GHOST_kWindowStateMaximized: | case GHOST_kWindowStateMaximized: | ||||
| [m_window zoom:nil]; | [m_window zoom:nil]; | ||||
| break; | break; | ||||
| case GHOST_kWindowStateFullScreen: | case GHOST_kWindowStateFullScreen: | ||||
| { | { | ||||
| NSUInteger masks = [m_window styleMask]; | NSUInteger masks = [m_window styleMask]; | ||||
| if (!(masks & NSFullScreenWindowMask)) { | if (!(masks & NSFullScreenWindowMask)) { | ||||
| [m_window toggleFullScreen:nil]; | [m_window toggleFullScreen:nil]; | ||||
| } | } | ||||
| break; | break; | ||||
| Show All 16 Lines | GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state) | ||||
| } | } | ||||
| return GHOST_kSuccess; | return GHOST_kSuccess; | ||||
| } | } | ||||
| GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges) | GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges) | ||||
| { | { | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| [m_window setDocumentEdited:isUnsavedChanges]; | [m_window setDocumentEdited:isUnsavedChanges]; | ||||
| [pool drain]; | [pool drain]; | ||||
| return GHOST_Window::setModifiedState(isUnsavedChanges); | return GHOST_Window::setModifiedState(isUnsavedChanges); | ||||
| } | } | ||||
| GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order) | GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order) | ||||
| { | { | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid"); | GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid"); | ||||
| if (order == GHOST_kWindowOrderTop) { | if (order == GHOST_kWindowOrderTop) { | ||||
| [m_window makeKeyAndOrderFront:nil]; | [m_window makeKeyAndOrderFront:nil]; | ||||
| } | } | ||||
| else { | else { | ||||
| NSArray *windowsList; | NSArray *windowsList; | ||||
| [m_window orderBack:nil]; | [m_window orderBack:nil]; | ||||
| //Check for other blender opened windows and make the frontmost key | //Check for other blender opened windows and make the frontmost key | ||||
| windowsList = [NSApp orderedWindows]; | windowsList = [NSApp orderedWindows]; | ||||
| if ([windowsList count]) { | if ([windowsList count]) { | ||||
| [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; | [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil]; | ||||
| } | } | ||||
| } | } | ||||
| [pool drain]; | [pool drain]; | ||||
| return GHOST_kSuccess; | return GHOST_kSuccess; | ||||
| } | } | ||||
| #pragma mark Drawing context | #pragma mark Drawing context | ||||
| GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType type) | GHOST_Context *GHOST_WindowCocoa::newDrawingContext(GHOST_TDrawingContextType type) | ||||
| { | { | ||||
| Show All 35 Lines | GHOST_TSuccess GHOST_WindowCocoa::invalidate() | ||||
| return GHOST_kSuccess; | return GHOST_kSuccess; | ||||
| } | } | ||||
| #pragma mark Progress bar | #pragma mark Progress bar | ||||
| GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress) | GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress) | ||||
| { | { | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| if ((progress >=0.0) && (progress <=1.0)) { | if ((progress >=0.0) && (progress <=1.0)) { | ||||
| NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)]; | NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)]; | ||||
| [dockIcon lockFocus]; | [dockIcon lockFocus]; | ||||
| NSRect progressBox = {{4, 4}, {120, 16}}; | NSRect progressBox = {{4, 4}, {120, 16}}; | ||||
| [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; | [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; | ||||
| // Track & Outline | // Track & Outline | ||||
| [[NSColor blackColor] setFill]; | [[NSColor blackColor] setFill]; | ||||
| NSRectFill(progressBox); | NSRectFill(progressBox); | ||||
| [[NSColor whiteColor] set]; | [[NSColor whiteColor] set]; | ||||
| NSFrameRect(progressBox); | NSFrameRect(progressBox); | ||||
| // Progress fill | // Progress fill | ||||
| progressBox = NSInsetRect(progressBox, 1, 1); | progressBox = NSInsetRect(progressBox, 1, 1); | ||||
| progressBox.size.width = progressBox.size.width * progress; | progressBox.size.width = progressBox.size.width * progress; | ||||
| NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:[NSColor darkGrayColor] endingColor:[NSColor lightGrayColor]]; | NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:[NSColor darkGrayColor] endingColor:[NSColor lightGrayColor]]; | ||||
| [gradient drawInRect:progressBox angle:90]; | [gradient drawInRect:progressBox angle:90]; | ||||
| [gradient release]; | [gradient release]; | ||||
| [dockIcon unlockFocus]; | [dockIcon unlockFocus]; | ||||
| [NSApp setApplicationIconImage:dockIcon]; | [NSApp setApplicationIconImage:dockIcon]; | ||||
| [dockIcon release]; | [dockIcon release]; | ||||
| m_progressBarVisible = true; | m_progressBarVisible = true; | ||||
| } | } | ||||
| [pool drain]; | [pool drain]; | ||||
| return GHOST_kSuccess; | return GHOST_kSuccess; | ||||
| } | } | ||||
| static void postNotification() | static void postNotification() | ||||
| { | { | ||||
| NSUserNotification *notification = [[NSUserNotification alloc] init]; | NSUserNotification *notification = [[NSUserNotification alloc] init]; | ||||
| notification.title = @"Blender progress notification"; | notification.title = @"Blender progress notification"; | ||||
| notification.informativeText = @"Calculation is finished"; | notification.informativeText = @"Calculation is finished"; | ||||
| notification.soundName = NSUserNotificationDefaultSoundName; | notification.soundName = NSUserNotificationDefaultSoundName; | ||||
| [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; | [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; | ||||
| [notification release]; | [notification release]; | ||||
| } | } | ||||
| GHOST_TSuccess GHOST_WindowCocoa::endProgressBar() | GHOST_TSuccess GHOST_WindowCocoa::endProgressBar() | ||||
| { | { | ||||
| if (!m_progressBarVisible) return GHOST_kFailure; | if (!m_progressBarVisible) return GHOST_kFailure; | ||||
| m_progressBarVisible = false; | m_progressBarVisible = false; | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)]; | NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)]; | ||||
| [dockIcon lockFocus]; | [dockIcon lockFocus]; | ||||
| [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; | [[NSImage imageNamed:@"NSApplicationIcon"] drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; | ||||
| [dockIcon unlockFocus]; | [dockIcon unlockFocus]; | ||||
| [NSApp setApplicationIconImage:dockIcon]; | [NSApp setApplicationIconImage:dockIcon]; | ||||
| // We use notifications to inform the user when the progress reached 100% | // We use notifications to inform the user when the progress reached 100% | ||||
| // Atm. just fire this when the progressbar ends, the behavior is controlled | // Atm. just fire this when the progressbar ends, the behavior is controlled | ||||
| // in the NotificationCenter If Blender is not frontmost window, a message | // in the NotificationCenter If Blender is not frontmost window, a message | ||||
| // pops up with sound, in any case an entry in notifications | // pops up with sound, in any case an entry in notifications | ||||
| if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) { | if ([NSUserNotificationCenter respondsToSelector:@selector(defaultUserNotificationCenter)]) { | ||||
| postNotification(); | postNotification(); | ||||
| } | } | ||||
| [dockIcon release]; | [dockIcon release]; | ||||
| [pool drain]; | [pool drain]; | ||||
| return GHOST_kSuccess; | return GHOST_kSuccess; | ||||
| } | } | ||||
| #pragma mark Cursor handling | #pragma mark Cursor handling | ||||
| void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const | void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const | ||||
| { | { | ||||
| static bool systemCursorVisible = true; | static bool systemCursorVisible = true; | ||||
| NSCursor *tmpCursor =nil; | NSCursor *tmpCursor =nil; | ||||
| if (visible != systemCursorVisible) { | if (visible != systemCursorVisible) { | ||||
| if (visible) { | if (visible) { | ||||
| [NSCursor unhide]; | [NSCursor unhide]; | ||||
| systemCursorVisible = true; | systemCursorVisible = true; | ||||
| } | } | ||||
| else { | else { | ||||
| [NSCursor hide]; | [NSCursor hide]; | ||||
| systemCursorVisible = false; | systemCursorVisible = false; | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const | ||||
| [tmpCursor set]; | [tmpCursor set]; | ||||
| } | } | ||||
| GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible) | GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible) | ||||
| { | { | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; | ||||
| if ([m_window isVisible]) { | if ([m_window isVisible]) { | ||||
| loadCursor(visible, getCursorShape()); | loadCursor(visible, getCursorShape()); | ||||
| } | } | ||||
| [pool drain]; | [pool drain]; | ||||
| return GHOST_kSuccess; | return GHOST_kSuccess; | ||||
| } | } | ||||
| GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode) | GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode) | ||||
| { | { | ||||
| GHOST_TSuccess err = GHOST_kSuccess; | GHOST_TSuccess err = GHOST_kSuccess; | ||||
| if (mode != GHOST_kGrabDisable) { | if (mode != GHOST_kGrabDisable) { | ||||
| //No need to perform grab without warp as it is always on in OS X | //No need to perform grab without warp as it is always on in OS X | ||||
| if (mode != GHOST_kGrabNormal) { | if (mode != GHOST_kGrabNormal) { | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| m_systemCocoa->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); | m_systemCocoa->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); | ||||
| setCursorGrabAccum(0, 0); | setCursorGrabAccum(0, 0); | ||||
| if (mode == GHOST_kGrabHide) { | if (mode == GHOST_kGrabHide) { | ||||
| setWindowCursorVisibility(false); | setWindowCursorVisibility(false); | ||||
| } | } | ||||
| //Make window key if it wasn't to get the mouse move events | //Make window key if it wasn't to get the mouse move events | ||||
| [m_window makeKeyWindow]; | [m_window makeKeyWindow]; | ||||
| [pool drain]; | [pool drain]; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (m_cursorGrab==GHOST_kGrabHide) { | if (m_cursorGrab==GHOST_kGrabHide) { | ||||
| m_systemCocoa->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); | m_systemCocoa->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); | ||||
| setWindowCursorVisibility(true); | setWindowCursorVisibility(true); | ||||
| } | } | ||||
| /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ | /* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */ | ||||
| setCursorGrabAccum(0, 0); | setCursorGrabAccum(0, 0); | ||||
| m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */ | m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */ | ||||
| } | } | ||||
| return err; | return err; | ||||
| } | } | ||||
| GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape) | GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape) | ||||
| { | { | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| if (m_customCursor) { | if (m_customCursor) { | ||||
| [m_customCursor release]; | [m_customCursor release]; | ||||
| m_customCursor = nil; | m_customCursor = nil; | ||||
| } | } | ||||
| if ([m_window isVisible]) { | if ([m_window isVisible]) { | ||||
| loadCursor(getCursorVisibility(), shape); | loadCursor(getCursorVisibility(), shape); | ||||
| } | } | ||||
| [pool drain]; | [pool drain]; | ||||
| return GHOST_kSuccess; | return GHOST_kSuccess; | ||||
| } | } | ||||
| /** Reverse the bits in a GHOST_TUns8 | /** Reverse the bits in a GHOST_TUns8 | ||||
| static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) | static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch) | ||||
| { | { | ||||
| ch= ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA); | ch= ((ch >> 1) & 0x55) | ((ch << 1) & 0xAA); | ||||
| Show All 18 Lines | GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask, | ||||
| int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color) | int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color) | ||||
| { | { | ||||
| int y,nbUns16; | int y,nbUns16; | ||||
| NSPoint hotSpotPoint; | NSPoint hotSpotPoint; | ||||
| NSBitmapImageRep *cursorImageRep; | NSBitmapImageRep *cursorImageRep; | ||||
| NSImage *cursorImage; | NSImage *cursorImage; | ||||
| NSSize imSize; | NSSize imSize; | ||||
| GHOST_TUns16 *cursorBitmap; | GHOST_TUns16 *cursorBitmap; | ||||
| NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; | ||||
| if (m_customCursor) { | if (m_customCursor) { | ||||
| [m_customCursor release]; | [m_customCursor release]; | ||||
| m_customCursor = nil; | m_customCursor = nil; | ||||
| } | } | ||||
| cursorImageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil | cursorImageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:nil | ||||
| pixelsWide:sizex | pixelsWide:sizex | ||||
| pixelsHigh:sizey | pixelsHigh:sizey | ||||
| bitsPerSample:1 | bitsPerSample:1 | ||||
| samplesPerPixel:2 | samplesPerPixel:2 | ||||
| hasAlpha:YES | hasAlpha:YES | ||||
| isPlanar:YES | isPlanar:YES | ||||
| colorSpaceName:NSDeviceWhiteColorSpace | colorSpaceName:NSDeviceWhiteColorSpace | ||||
| bytesPerRow:(sizex/8 + (sizex%8 >0 ?1:0)) | bytesPerRow:(sizex/8 + (sizex%8 >0 ?1:0)) | ||||
| bitsPerPixel:1]; | bitsPerPixel:1]; | ||||
| cursorBitmap = (GHOST_TUns16*)[cursorImageRep bitmapData]; | cursorBitmap = (GHOST_TUns16*)[cursorImageRep bitmapData]; | ||||
| nbUns16 = [cursorImageRep bytesPerPlane]/2; | nbUns16 = [cursorImageRep bytesPerPlane]/2; | ||||
| for (y=0; y<nbUns16; y++) { | for (y=0; y<nbUns16; y++) { | ||||
| #if !defined(__LITTLE_ENDIAN__) | #if !defined(__LITTLE_ENDIAN__) | ||||
| cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8)); | cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8)); | ||||
| cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8)); | cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8)); | ||||
| #else | #else | ||||
| cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8)); | cursorBitmap[y] = ~uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8)); | ||||
| cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8)); | cursorBitmap[nbUns16+y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8)); | ||||
| #endif | #endif | ||||
| } | } | ||||
| imSize.width = sizex; | imSize.width = sizex; | ||||
| imSize.height= sizey; | imSize.height= sizey; | ||||
| cursorImage = [[NSImage alloc] initWithSize:imSize]; | cursorImage = [[NSImage alloc] initWithSize:imSize]; | ||||
| [cursorImage addRepresentation:cursorImageRep]; | [cursorImage addRepresentation:cursorImageRep]; | ||||
| hotSpotPoint.x = hotX; | hotSpotPoint.x = hotX; | ||||
| hotSpotPoint.y = hotY; | hotSpotPoint.y = hotY; | ||||
| //foreground and background color parameter is not handled for now (10.6) | //foreground and background color parameter is not handled for now (10.6) | ||||
| m_customCursor = [[NSCursor alloc] initWithImage:cursorImage | m_customCursor = [[NSCursor alloc] initWithImage:cursorImage | ||||
| hotSpot:hotSpotPoint]; | hotSpot:hotSpotPoint]; | ||||
| [cursorImageRep release]; | [cursorImageRep release]; | ||||
| [cursorImage release]; | [cursorImage release]; | ||||
| if ([m_window isVisible]) { | if ([m_window isVisible]) { | ||||
| loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom); | loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom); | ||||
| } | } | ||||
| [pool drain]; | [pool drain]; | ||||
| return GHOST_kSuccess; | return GHOST_kSuccess; | ||||
| } | } | ||||
| GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], | GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], | ||||
| GHOST_TUns8 mask[16][2], int hotX, int hotY) | GHOST_TUns8 mask[16][2], int hotX, int hotY) | ||||
| { | { | ||||
| return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1); | return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1); | ||||
| } | } | ||||