]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/cocoa/utils.mm
Add wxTimer::StartOnce().
[wxWidgets.git] / src / osx / cocoa / utils.mm
index b35775be0612fa94b262172e54319c5fbaf0beba..66bf2fb6828e04ff0a8c0f6d0f8a9199a6507b10 100644 (file)
@@ -4,7 +4,7 @@
 // Author:      Stefan Csomor
 // Modified by:
 // Created:     1998-01-01
 // Author:      Stefan Csomor
 // Modified by:
 // Created:     1998-01-01
-// RCS-ID:      $Id: utils.mm 48805 2007-09-19 14:52:25Z SC $
+// RCS-ID:      $Id$
 // Copyright:   (c) Stefan Csomor
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 // Copyright:   (c) Stefan Csomor
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
@@ -37,7 +37,7 @@
 
 #if wxOSX_USE_COCOA
 
 
 #if wxOSX_USE_COCOA
 
-#if wxUSE_BASE
+#if wxUSE_GUI
 
 // Emit a beeeeeep
 void wxBell()
 
 // Emit a beeeeeep
 void wxBell()
@@ -45,29 +45,36 @@ void wxBell()
     NSBeep();
 }
 
     NSBeep();
 }
 
-#endif // wxUSE_BASE
-
-#if wxUSE_GUI
-
 @implementation wxNSAppController
 
 - (void)applicationWillFinishLaunching:(NSNotification *)application { 
     wxUnusedVar(application);
 @implementation wxNSAppController
 
 - (void)applicationWillFinishLaunching:(NSNotification *)application { 
     wxUnusedVar(application);
-}
+    
+    // we must install our handlers later than setting the app delegate, because otherwise our handlers
+    // get overwritten in the meantime
 
 
-- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename
-{
-    wxUnusedVar(sender);
-    wxCFStringRef cf(wxCFRetain(filename));
-    wxTheApp->MacOpenFile(cf.AsString()) ;
-    return YES;
+    NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
+    
+    [appleEventManager setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:)
+                         forEventClass:kInternetEventClass andEventID:kAEGetURL];
+    
+    [appleEventManager setEventHandler:self andSelector:@selector(handleOpenAppEvent:withReplyEvent:)
+                         forEventClass:kCoreEventClass andEventID:kAEOpenApplication];
+    
 }
 
 }
 
-- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
+- (void)application:(NSApplication *)sender openFiles:(NSArray *)fileNames
 {
     wxUnusedVar(sender);
 {
     wxUnusedVar(sender);
-    wxTheApp->MacNewFile() ;
-    return NO;
+    wxArrayString fileList;
+    size_t i;
+    const size_t count = [fileNames count];
+    for (i = 0; i < count; i++)
+    {
+        fileList.Add( wxCFStringRef::AsStringWithNormalizationFormC([fileNames objectAtIndex:i]) );
+    }
+
+    wxTheApp->MacOpenFiles(fileList);
 }
 
 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
 }
 
 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
@@ -95,6 +102,13 @@ void wxBell()
     wxTheApp->MacOpenURL(cf.AsString()) ;
 }
 
     wxTheApp->MacOpenURL(cf.AsString()) ;
 }
 
+- (void)handleOpenAppEvent:(NSAppleEventDescriptor *)event
+           withReplyEvent:(NSAppleEventDescriptor *)replyEvent
+{
+    wxUnusedVar(replyEvent);
+    wxTheApp->MacNewFile() ;
+}
+
 /*
     Allowable return values are:
         NSTerminateNow - it is ok to proceed with termination
 /*
     Allowable return values are:
         NSTerminateNow - it is ok to proceed with termination
@@ -179,7 +193,7 @@ void wxBell()
 @implementation ModalDialogDelegate
 - (id)init
 {
 @implementation ModalDialogDelegate
 - (id)init
 {
-    [super init];
+    self = [super init];
     sheetFinished = NO;
     resultCode = -1;
     impl = 0;
     sheetFinished = NO;
     resultCode = -1;
     impl = 0;
@@ -223,31 +237,73 @@ void wxBell()
 }
 @end
 
 }
 @end
 
+// here we subclass NSApplication, for the purpose of being able to override sendEvent.
+@interface wxNSApplication : NSApplication
+{
+}
+
+- (void)sendEvent:(NSEvent *)anEvent;
+
+@end
+
+@implementation wxNSApplication
+
+/* This is needed because otherwise we don't receive any key-up events for command-key
+ combinations (an AppKit bug, apparently)                      */
+- (void)sendEvent:(NSEvent *)anEvent
+{
+    if ([anEvent type] == NSKeyUp && ([anEvent modifierFlags] & NSCommandKeyMask))
+        [[self keyWindow] sendEvent:anEvent];
+    else [super sendEvent:anEvent];
+}
+
+@end
+
+WX_NSObject appcontroller = nil;
+
+NSLayoutManager* gNSLayoutManager = nil;
+
+WX_NSObject wxApp::OSXCreateAppController()
+{
+    return [[wxNSAppController alloc] init];
+}
+
 bool wxApp::DoInitGui()
 {
     wxMacAutoreleasePool pool;
 bool wxApp::DoInitGui()
 {
     wxMacAutoreleasePool pool;
-    [NSApplication sharedApplication];
 
     if (!sm_isEmbedded)
     {
 
     if (!sm_isEmbedded)
     {
-        wxNSAppController* controller = [[wxNSAppController alloc] init];
-        [NSApp setDelegate:controller];
+        [wxNSApplication sharedApplication];
+
+        appcontroller = OSXCreateAppController();
+        [NSApp setDelegate:appcontroller];
+        [NSColor setIgnoresAlpha:NO];
 
 
-        NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
-        [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
-            forEventClass:kInternetEventClass andEventID:kAEGetURL];
-   
         // calling finishLaunching so early before running the loop seems to trigger some 'MenuManager compatibility' which leads
         // to the duplication of menus under 10.5 and a warning under 10.6
 #if 0
         [NSApp finishLaunching];
 #endif
     }
         // calling finishLaunching so early before running the loop seems to trigger some 'MenuManager compatibility' which leads
         // to the duplication of menus under 10.5 and a warning under 10.6
 #if 0
         [NSApp finishLaunching];
 #endif
     }
+    gNSLayoutManager = [[NSLayoutManager alloc] init];
+    
     return true;
 }
 
 void wxApp::DoCleanUp()
 {
     return true;
 }
 
 void wxApp::DoCleanUp()
 {
+    if ( appcontroller != nil )
+    {
+        [NSApp setDelegate:nil];
+        [appcontroller release];
+        appcontroller = nil;
+    }
+    if ( gNSLayoutManager != nil )
+    {
+        [gNSLayoutManager release];
+        gNSLayoutManager = nil;
+    }
 }
 
 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
 }
 
 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
@@ -291,10 +347,10 @@ wxMouseState wxGetMouseState()
     ms.SetMiddleDown( (buttons & 0x04) != 0 );
     ms.SetRightDown( (buttons & 0x02) != 0 );
     
     ms.SetMiddleDown( (buttons & 0x04) != 0 );
     ms.SetRightDown( (buttons & 0x02) != 0 );
     
-    ms.SetControlDown(modifiers & NSControlKeyMask);
+    ms.SetRawControlDown(modifiers & NSControlKeyMask);
     ms.SetShiftDown(modifiers & NSShiftKeyMask);
     ms.SetAltDown(modifiers & NSAlternateKeyMask);
     ms.SetShiftDown(modifiers & NSShiftKeyMask);
     ms.SetAltDown(modifiers & NSAlternateKeyMask);
-    ms.SetMetaDown(modifiers & NSCommandKeyMask);
+    ms.SetControlDown(modifiers & NSCommandKeyMask);
     
     return ms;
 }
     
     return ms;
 }
@@ -379,7 +435,7 @@ wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
         [view lockFocus];
         // we use this method as other methods force a repaint, and this method can be
         // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
         [view lockFocus];
         // we use this method as other methods force a repaint, and this method can be
         // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
-        NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
+        NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]];
         [view unlockFocus];
         if ( [rep respondsToSelector:@selector(CGImage)] )
         {
         [view unlockFocus];
         if ( [rep respondsToSelector:@selector(CGImage)] )
         {
@@ -388,8 +444,6 @@ wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
             CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef)  , CGImageGetHeight(cgImageRef) );
             // since our context is upside down we dont use CGContextDrawImage
             wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
             CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef)  , CGImageGetHeight(cgImageRef) );
             // since our context is upside down we dont use CGContextDrawImage
             wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
-            CGImageRelease(cgImageRef);
-            cgImageRef = NULL;
         }
         else
         {
         }
         else
         {