]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/toplevel.cpp
added wxArray::SetCount()
[wxWidgets.git] / src / mac / toplevel.cpp
index 8db3f7e902143b929de3273c07e21413c9e0cef5..b9acd02cc0d5b52ea3e93eb79e9332a6b7b780f7 100644 (file)
@@ -39,6 +39,7 @@
 
 #include "wx/mac/uma.h"
 #include "wx/mac/aga.h"
+#include "wx/app.h"
 #include "wx/tooltip.h"
 #include "wx/dnd.h"
 
 // ----------------------------------------------------------------------------
 
 // list of all frames and modeless dialogs
-wxWindowList wxModelessWindows;
+wxWindowList       wxModelessWindows;
+
+// double click testing
+static   Point     gs_lastWhere;
+static   long      gs_lastWhen = 0;
 
 // ============================================================================
 // wxTopLevelWindowMac implementation
@@ -70,7 +75,7 @@ wxTopLevelWindowMac *wxFindWinFromMacWindow(WXWindow inWindowRef)
     wxNode *node = wxWinMacWindowList->Find((long)inWindowRef);
     if (!node)
         return NULL;
-    return (wxTopLevelWindowMac *)node->Data();
+    return (wxTopLevelWindowMac *)node->GetData();
 }
 
 void wxAssociateWinWithMacWindow(WXWindow inWindowRef, wxTopLevelWindowMac *win)
@@ -102,8 +107,24 @@ void wxTopLevelWindowMac::Init()
     m_macNoEraseUpdateRgn = NewRgn() ;
     m_macNeedsErasing = false ;
     m_macWindow = NULL ;
+    m_macEventHandler = NULL ;
 }
 
+class wxMacDeferredWindowDeleter : public wxObject
+{
+public :
+    wxMacDeferredWindowDeleter( WindowRef windowRef ) 
+    { 
+        m_macWindow = windowRef ; 
+    }
+    virtual ~wxMacDeferredWindowDeleter() 
+    { 
+        UMADisposeWindow( (WindowRef) m_macWindow ) ; 
+    }
+ protected :
+    WindowRef m_macWindow ;
+} ;
+
 bool wxTopLevelWindowMac::Create(wxWindow *parent,
                                  wxWindowID id,
                                  const wxString& title,
@@ -134,26 +155,21 @@ wxTopLevelWindowMac::~wxTopLevelWindowMac()
     if ( m_macWindow )
     {
         wxToolTip::NotifyWindowDelete(m_macWindow) ;
-        UMADisposeWindow( (WindowRef) m_macWindow ) ;
+        wxPendingDelete.Append( new wxMacDeferredWindowDeleter( (WindowRef) m_macWindow ) ) ;
     }
-    
+#if TARGET_CARBON
+    if ( m_macEventHandler )
+    {
+        ::RemoveEventHandler((EventHandlerRef) m_macEventHandler);
+        m_macEventHandler = NULL ;
+    }
+#endif   
     wxRemoveMacWindowAssociation( this ) ;
 
-    wxTopLevelWindows.DeleteObject(this);
-
     if ( wxModelessWindows.Find(this) )
         wxModelessWindows.DeleteObject(this);
 
-    // If this is the last top-level window, exit.
-    if ( wxTheApp && (wxTopLevelWindows.Number() == 0) )
-    {
-        wxTheApp->SetTopWindow(NULL);
-
-        if ( wxTheApp->GetExitOnFrameDelete() )
-        {
-          wxTheApp->ExitMainLoop() ;        
-        }
-    }
     DisposeRgn( (RgnHandle) m_macNoEraseUpdateRgn ) ;
 }
 
@@ -198,6 +214,59 @@ void wxTopLevelWindowMac::SetIcon(const wxIcon& icon)
     wxTopLevelWindowBase::SetIcon(icon);
 }
 
+#if TARGET_CARBON
+
+EventHandlerUPP wxMacWindowEventHandlerUPP = NULL ;
+
+extern long wxMacTranslateKey(unsigned char key, unsigned char code) ;
+
+pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
+{
+    OSStatus result = eventNotHandledErr ;
+    EventRecord rec ;
+    switch ( GetEventClass( event ) )
+    {
+        case kEventClassTextInput :
+            if ( wxMacConvertEventToRecord( event , &rec ) )
+            {
+                       wxTheApp->m_macCurrentEvent = &rec ;
+                wxWindow* focus = wxWindow::FindFocus() ;
+                if ( (focus != NULL) && !UMAMenuEvent(&rec) && wxTheApp->MacSendKeyDownEvent( focus , rec.message , rec.modifiers , rec.when , rec.where.h , rec.where.v ) )
+                {
+                    // was handled internally
+                    result = noErr ;
+                }
+            }
+            break ;
+        default :
+            break ;
+    }
+    return result ;
+}
+
+#endif
+
+void wxTopLevelWindowMac::MacInstallEventHandler()
+{
+#if TARGET_CARBON
+       if ( wxMacWindowEventHandlerUPP == NULL )
+       {
+           wxMacWindowEventHandlerUPP = NewEventHandlerUPP( wxMacWindowEventHandler ) ;
+       }
+           
+       static const EventTypeSpec eventList[] = 
+       {
+           { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent }
+       } ;
+       if ( m_macEventHandler )
+       {
+        ::RemoveEventHandler((EventHandlerRef) m_macEventHandler);
+        m_macEventHandler = NULL ;
+    }
+       InstallWindowEventHandler(MAC_WXHWND(m_macWindow), wxMacWindowEventHandlerUPP, WXSIZEOF(eventList), eventList, this, &((EventHandlerRef)m_macEventHandler));    
+#endif
+}
+
 void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
            const wxPoint& pos,
            const wxSize& size,
@@ -233,12 +302,27 @@ void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
     WindowClass wclass = 0;
     WindowAttributes attr = kWindowNoAttributes ;
     
-    if ( HasFlag( wxFRAME_TOOL_WINDOW) || HasFlag(wxTINY_CAPTION_HORIZ) ||  HasFlag(wxTINY_CAPTION_VERT) )
+    if ( HasFlag( wxFRAME_TOOL_WINDOW) )
     {
-        wclass = kFloatingWindowClass ;
-        if ( HasFlag(wxTINY_CAPTION_VERT) )
+        if ( 
+            HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
+            HasFlag( wxSYSTEM_MENU ) || HasFlag( wxCAPTION ) ||
+            HasFlag(wxTINY_CAPTION_HORIZ) ||  HasFlag(wxTINY_CAPTION_VERT)
+             )
         {
-            attr |= kWindowSideTitlebarAttribute ;
+            wclass = kFloatingWindowClass ;
+            if ( HasFlag(wxTINY_CAPTION_VERT) )
+            {
+                attr |= kWindowSideTitlebarAttribute ;
+            }
+        }
+        else
+        {
+#if TARGET_CARBON
+            wclass = kPlainWindowClass ;
+#else
+            wclass = kFloatingWindowClass ;
+#endif
         }
     }
     else if ( HasFlag( wxCAPTION ) )
@@ -254,7 +338,19 @@ void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
     }
     else
     {
-        wclass = kModalWindowClass ;
+        if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
+             HasFlag( wxSYSTEM_MENU ) )
+        {
+            wclass = kDocumentWindowClass ;
+        }
+        else
+        {
+#if TARGET_CARBON
+            wclass = kPlainWindowClass ;
+#else
+            wclass = kModalWindowClass ;
+#endif
+        }
     }
     
     if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) )
@@ -280,6 +376,7 @@ void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
         label = title ;
     UMASetWTitleC( (WindowRef)m_macWindow , label ) ;
     ::CreateRootControl( (WindowRef)m_macWindow , (ControlHandle*)&m_macRootControl ) ;
+    MacInstallEventHandler() ;
 
     m_macFocus = NULL ;
 }
@@ -347,10 +444,6 @@ void wxTopLevelWindowMac::Lower()
     ::SendBehind( (WindowRef)m_macWindow , NULL ) ;
 }
 
-Point lastWhere ;
-long lastWhen = 0 ;
-extern int wxBusyCursorCount ;
-
 void wxTopLevelWindowMac::MacFireMouseEvent( WXEVENTREF evr )
 {
     EventRecord *ev = (EventRecord*) evr ;
@@ -397,22 +490,25 @@ void wxTopLevelWindowMac::MacFireMouseEvent( WXEVENTREF evr )
 
     if ( ev->what == mouseDown )
     {
-        if ( ev->when - lastWhen <= GetDblTime() )
+        if ( ev->when - gs_lastWhen <= GetDblTime() )
         {
-            if ( abs( localwhere.h - lastWhere.h ) < 3 || abs( localwhere.v - lastWhere.v ) < 3 )
+            if ( abs( localwhere.h - gs_lastWhere.h ) < 3 && abs( localwhere.v - gs_lastWhere.v ) < 3 )
             {
+                // This is not right if the second mouse down
+                // event occured in a differen window. We
+                // correct this in MacDispatchMouseEvent.
                 if ( controlDown )
                     event.SetEventType(wxEVT_RIGHT_DCLICK ) ;
                 else
                     event.SetEventType(wxEVT_LEFT_DCLICK ) ;
             }
-            lastWhen = 0 ;
+            gs_lastWhen = 0 ;
         }
         else
         {
-            lastWhen = ev->when ;
+            gs_lastWhen = ev->when ;
         }
-        lastWhere = localwhere ;
+        gs_lastWhere = localwhere ;
     }
 
     event.m_x = localwhere.h;
@@ -435,7 +531,7 @@ void wxTopLevelWindowMac::MacFireMouseEvent( WXEVENTREF evr )
         if ( ev->what == mouseUp )
         {
             wxTheApp->s_captureWindow = NULL ;
-            if ( wxBusyCursorCount == 0 )
+            if ( !wxIsBusy() )
             {
                 m_cursor.MacInstall() ;
             }
@@ -485,7 +581,13 @@ void wxTopLevelWindowMac::MacActivate( WXEVENTREF ev , bool inIsActivating )
     
     UMAHighlightAndActivateWindow( (WindowRef)m_macWindow , inIsActivating ) ;
     
-    MacSuperEnabled( inIsActivating ) ;
+    // Early versions of MacOS X don't refresh backgrounds properly,
+    // so refresh the whole window on activation and deactivation.
+    long osVersion = UMAGetSystemVersion();
+    if (osVersion >= 0x1000 && osVersion < 0x1020)
+        Refresh(TRUE);
+    else
+        MacSuperEnabled( inIsActivating ) ;
 }
 
 void wxTopLevelWindowMac::MacKeyDown( WXEVENTREF ev ) 
@@ -512,8 +614,8 @@ bool wxTopLevelWindowMac::Show(bool show)
         return FALSE;
 
     if (show)
-    {
-      ::ShowWindow( (WindowRef)m_macWindow ) ;
+    { 
+      ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowShowTransitionAction,nil);
       ::SelectWindow( (WindowRef)m_macWindow ) ;
       // no need to generate events here, they will get them triggered by macos
       // actually they should be , but apparently they are not
@@ -524,7 +626,7 @@ bool wxTopLevelWindowMac::Show(bool show)
     }
     else
     {
-      ::HideWindow( (WindowRef)m_macWindow ) ;
+      ::TransitionWindow((WindowRef)m_macWindow,kWindowZoomTransitionEffect,kWindowHideTransitionAction,nil);
     }
 
     if ( !show )
@@ -583,9 +685,13 @@ void wxTopLevelWindowMac::DoMoveWindow(int x, int y, int width, int height)
         
         if ( doResize )
             ::SizeWindow((WindowRef)m_macWindow, m_width, m_height  , true); 
+            
+        // the OS takes care of invalidating and erasing the new area so we only have to
+        // take care of refreshing for full repaints
+
+        if ( doResize && !HasFlag(wxNO_FULL_REPAINT_ON_RESIZE) )
+            Refresh() ;
         
-        // the OS takes care of invalidating and erasing the new area
-        // we have erased the old one   
         
         if ( IsKindOf( CLASSINFO( wxFrame ) ) )
         {