]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/toplevel.cpp
fixed background drawing for opaque controls
[wxWidgets.git] / src / mac / carbon / toplevel.cpp
index afeecbafc44a172c44e984fc7274618c583b15dd..a54c02df217ad617d523ae71fef39b5af13647c9 100644 (file)
@@ -49,6 +49,9 @@
 
 #include <ToolUtils.h>
 
+//For targeting OSX
+#include "wx/mac/private.h"
+
 // ----------------------------------------------------------------------------
 // globals
 // ----------------------------------------------------------------------------
@@ -283,6 +286,9 @@ static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent )
     
     if ( cEvent.GetKind() == kEventMouseDown )
         lastButton = button ;
+        
+    if ( button == 0 )
+        lastButton = 0 ;    
     else if ( lastButton )
         button = lastButton ;
 
@@ -303,29 +309,39 @@ static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent )
                 break ;
         }
     }
-    // determinate the correct click button
-    if ( button == kEventMouseButtonSecondary )
-    {
-        if (cEvent.GetKind() == kEventMouseDown )
-            wxevent.SetEventType( clickCount > 1 ? wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN ) ;
-        else if ( cEvent.GetKind() == kEventMouseUp )
-            wxevent.SetEventType(wxEVT_RIGHT_UP ) ;
-    }
-    else if ( button == kEventMouseButtonTertiary )
-    {
-        if (cEvent.GetKind() == kEventMouseDown )
-            wxevent.SetEventType(clickCount > 1 ? wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN ) ;
-        else if ( cEvent.GetKind() == kEventMouseUp )
-            wxevent.SetEventType(wxEVT_MIDDLE_UP ) ;
-    }
-    else
+    // translate into wx types
+    switch ( cEvent.GetKind() )
     {
-        if (cEvent.GetKind() == kEventMouseDown )
-            wxevent.SetEventType(clickCount > 1 ? wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN ) ;
-        else if ( cEvent.GetKind() == kEventMouseUp )
-            wxevent.SetEventType(wxEVT_LEFT_UP ) ;
-        else if ( cEvent.GetKind() == kEventMouseWheelMoved )
-        {
+        case kEventMouseDown :
+            switch( button )
+            {
+                case kEventMouseButtonPrimary :
+                    wxevent.SetEventType(clickCount > 1 ? wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN )  ;
+                    break ;
+                case kEventMouseButtonSecondary :
+                    wxevent.SetEventType( clickCount > 1 ? wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN ) ;
+                    break ;
+                case kEventMouseButtonTertiary :
+                    wxevent.SetEventType(clickCount > 1 ? wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN ) ;
+                    break ;
+            }
+            break ;
+        case kEventMouseUp :
+            switch( button )
+            {
+                case kEventMouseButtonPrimary :
+                    wxevent.SetEventType( wxEVT_LEFT_UP )  ;
+                    break ;
+                case kEventMouseButtonSecondary :
+                    wxevent.SetEventType( wxEVT_RIGHT_UP ) ;
+                    break ;
+                case kEventMouseButtonTertiary :
+                    wxevent.SetEventType( wxEVT_MIDDLE_UP ) ;
+                    break ;
+            }
+            break ;
+     case kEventMouseWheelMoved :
+         {
             wxevent.SetEventType(wxEVT_MOUSEWHEEL ) ;
 
             // EventMouseWheelAxis axis = cEvent.GetParameter<EventMouseWheelAxis>(kEventParamMouseWheelAxis, typeMouseWheelAxis) ;
@@ -334,12 +350,12 @@ static void SetupMouseEvent( wxMouseEvent &wxevent , wxMacCarbonEvent &cEvent )
             wxevent.m_wheelRotation = delta;
             wxevent.m_wheelDelta = 1;
             wxevent.m_linesPerAction = 1;
-        }
-        else
+            break ;
+         }
+        default :
             wxevent.SetEventType(wxEVT_MOTION ) ;
-    }
-    if ( cEvent.GetKind() == kEventMouseUp )
-        lastButton = 0 ;
+            break ;
+    }       
 }
 
 ControlRef wxMacFindSubControl( Point location , ControlRef superControl , ControlPartCode *outPart )
@@ -411,7 +427,8 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev
     short windowPart = ::FindWindow(screenMouseLocation, &window);
 
     wxWindow* currentMouseWindow = NULL ;
-
+    ControlRef control = NULL ;
+    
     if ( window )
     {
         QDGlobalToLocalPoint( UMAGetWindowPort(window ) ,  &windowMouseLocation ) ;
@@ -423,14 +440,27 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev
         else if ( (IsWindowActive(window) && windowPart == inContent) )
         {
             ControlPartCode part ;
-            ControlRef control = wxMacFindControlUnderMouse( windowMouseLocation , window , &part ) ;
+            control = wxMacFindControlUnderMouse( windowMouseLocation , window , &part ) ;
+            // if there is no control below the mouse position, send the event to the toplevel window itself
             if ( control == 0 )
                 currentMouseWindow = (wxWindow*) data ;
             else
+            {
                 currentMouseWindow = wxFindControlFromMacControl( control ) ;
+                if ( currentMouseWindow == NULL && cEvent.GetKind() == kEventMouseMoved )
+                {
+                       // for wxToolBar to function we have to send certaint events to it
+                       // instead of its children (wxToolBarTools)     
+                    ControlRef parent ;
+                    GetSuperControl(control, &parent );
+                    wxWindow *wxParent = wxFindControlFromMacControl( parent ) ;
+                    if ( wxParent && wxParent->IsKindOf( CLASSINFO( wxToolBar ) ) )
+                        currentMouseWindow = wxParent ;
+                }
+            }
         }        
     }
-
+    
     wxMouseEvent wxevent(wxEVT_LEFT_DOWN);
     SetupMouseEvent( wxevent , cEvent ) ;
 
@@ -491,15 +521,6 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev
                 cursorPoint += cursorTarget->GetPosition() ;
         }
 
-        // update focus
-
-        if ( wxevent.GetEventType() == wxEVT_LEFT_DOWN )
-        {
-            // set focus to this window
-            if (currentMouseWindow->AcceptsFocus() && wxWindow::FindFocus()!=currentMouseWindow)
-                currentMouseWindow->SetFocus();
-        }
-
         // make tooltips current
         
     #if wxUSE_TOOLTIPS
@@ -512,6 +533,15 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev
             result = noErr;
         else
         {
+            // if the user code did _not_ handle the event, then perform the
+            // default processing
+            if ( wxevent.GetEventType() == wxEVT_LEFT_DOWN )
+            {
+                // ... that is set focus to this window
+                if (currentMouseWindow->AcceptsFocus() && wxWindow::FindFocus()!=currentMouseWindow)
+                    currentMouseWindow->SetFocus();
+            }
+
             ControlPartCode dummyPart ;
             // if built-in find control is finding the wrong control (ie static box instead of overlaid
             // button, we cannot let the standard handler do its job, but must handle manually
@@ -520,13 +550,16 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev
                 (FindControlUnderMouse(windowMouseLocation , window , &dummyPart) != 
                 wxMacFindControlUnderMouse( windowMouseLocation , window , &dummyPart ) ) )
             {
-                EventModifiers modifiers = cEvent.GetParameter<EventModifiers>(kEventParamKeyModifiers, typeUInt32) ;
-                Point clickLocation = windowMouseLocation ;
-#if TARGET_API_MAC_OSX
-                currentMouseWindow->MacRootWindowToWindow( &clickLocation.h , &clickLocation.v ) ;
-#endif
-                HandleControlClick( (ControlRef) currentMouseWindow->GetHandle() , clickLocation ,
-                    modifiers , (ControlActionUPP ) -1 ) ;
+                if ( currentMouseWindow->MacIsReallyEnabled() ) 
+                {
+                    EventModifiers modifiers = cEvent.GetParameter<EventModifiers>(kEventParamKeyModifiers, typeUInt32) ;
+                    Point clickLocation = windowMouseLocation ;
+    #if TARGET_API_MAC_OSX
+                    currentMouseWindow->MacRootWindowToWindow( &clickLocation.h , &clickLocation.v ) ;
+    #endif
+                    HandleControlClick( (ControlRef) currentMouseWindow->GetHandle() , clickLocation ,
+                        modifiers , (ControlActionUPP ) -1 ) ;
+                }
                 result = noErr ;
             }
         }
@@ -536,6 +569,29 @@ pascal OSStatus wxMacTopLevelMouseEventHandler( EventHandlerCallRef handler , Ev
             // update cursor ?
          }
     } // else if ( currentMouseWindow )
+    else
+    {
+        // don't mess with controls we don't know about
+        // for some reason returning eventNotHandledErr does not lead to the correct behaviour
+        // so we try sending them the correct control directly
+        wxTopLevelWindowMac* toplevelWindow = (wxTopLevelWindowMac*) data ;
+        if ( cEvent.GetKind() == kEventMouseDown && toplevelWindow && control )
+        {
+            EventModifiers modifiers = cEvent.GetParameter<EventModifiers>(kEventParamKeyModifiers, typeUInt32) ;
+            Point clickLocation = windowMouseLocation ;
+#if TARGET_API_MAC_OSX
+            HIPoint hiPoint ;
+            hiPoint.x = clickLocation.h ;
+            hiPoint.y = clickLocation.v ;
+            HIViewConvertPoint( &hiPoint , (ControlRef) toplevelWindow->GetHandle() , control  ) ;
+            clickLocation.h = (int)hiPoint.x ;
+            clickLocation.v = (int)hiPoint.y ;
+#endif
+            HandleControlClick( control , clickLocation ,
+                modifiers , (ControlActionUPP ) -1 ) ;
+            result = noErr ;
+        }
+    }
     return result ;
 }
 
@@ -685,6 +741,7 @@ DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacTopLevelEventHandler )
 
 // Find an item given the Macintosh Window Reference
 
+#if KEY_wxList_DEPRECATED
 wxList wxWinMacWindowList(wxKEY_INTEGER);
 wxTopLevelWindowMac *wxFindWinFromMacWindow(WindowRef inWindowRef)
 {
@@ -710,7 +767,43 @@ void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
 {
     wxWinMacWindowList.DeleteObject(win);
 }
+#else
+
+WX_DECLARE_HASH_MAP(WindowRef, wxTopLevelWindowMac*, wxPointerHash, wxPointerEqual, MacWindowMap);
+
+static MacWindowMap wxWinMacWindowList;
+
+wxTopLevelWindowMac *wxFindWinFromMacWindow(WindowRef inWindowRef)
+{
+    MacWindowMap::iterator node = wxWinMacWindowList.find(inWindowRef);
+
+    return (node == wxWinMacWindowList.end()) ? NULL : node->second;
+}
+
+void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxTopLevelWindowMac *win) ;
+void wxAssociateWinWithMacWindow(WindowRef inWindowRef, wxTopLevelWindowMac *win)
+{
+    // adding NULL WindowRef is (first) surely a result of an error and
+    // nothing else :-)
+    wxCHECK_RET( inWindowRef != (WindowRef) NULL, wxT("attempt to add a NULL WindowRef to window list") );
 
+    wxWinMacWindowList[inWindowRef] = win;
+}
+
+void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win) ;
+void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
+{
+    MacWindowMap::iterator it;
+    for ( it = wxWinMacWindowList.begin(); it != wxWinMacWindowList.end(); ++it )
+    {
+        if ( it->second == win )
+        {
+            wxWinMacWindowList.erase(it);
+            break;
+        }
+    }
+}
+#endif // deprecated wxList
 
 // ----------------------------------------------------------------------------
 // wxTopLevelWindowMac creation
@@ -718,6 +811,12 @@ void wxRemoveMacWindowAssociation(wxTopLevelWindowMac *win)
 
 wxTopLevelWindowMac *wxTopLevelWindowMac::s_macDeactivateWindow = NULL;
 
+typedef struct 
+{
+    wxPoint m_position ;
+    wxSize m_size ;  
+} FullScreenData ;
+
 void wxTopLevelWindowMac::Init()
 {
     m_iconized =
@@ -729,6 +828,7 @@ void wxTopLevelWindowMac::Init()
     m_macUsesCompositing = FALSE;
 #endif
     m_macEventHandler = NULL ;
+    m_macFullScreenData = NULL ;
 }
 
 class wxMacDeferredWindowDeleter : public wxObject
@@ -762,6 +862,7 @@ bool wxTopLevelWindowMac::Create(wxWindow *parent,
     SetName(name);
 
     m_windowId = id == -1 ? NewControlId() : id;
+    wxWindow::SetTitle( title ) ;
 
     MacCreateRealWindow( title, pos , size , MacRemoveBordersFromStyle(style) , name ) ;
 
@@ -793,6 +894,10 @@ wxTopLevelWindowMac::~wxTopLevelWindowMac()
 
     if ( wxModelessWindows.Find(this) )
         wxModelessWindows.DeleteObject(this);
+        
+    FullScreenData *data = (FullScreenData *) m_macFullScreenData ;
+    delete data ;
+    m_macFullScreenData = NULL ;
 }
 
 
@@ -880,10 +985,14 @@ void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
 
     int x = (int)pos.x;
     int y = (int)pos.y;
-    if ( y < 50 )
-        y = 50 ;
-    if ( x < 20 )
-        x = 20 ;
+    
+    wxRect display = wxGetClientDisplayRect() ;
+
+    if ( x == wxDefaultPosition.x )
+        x = display.x ;
+    
+    if ( y == wxDefaultPosition.y )
+        y = display.y ;
 
     int w = WidthDefault(size.x);
     int h = HeightDefault(size.y);
@@ -918,6 +1027,16 @@ void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
     {
         wclass = kDocumentWindowClass ;
     }
+#if defined( __WXMAC__ ) && TARGET_API_MAC_OSX && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2 )
+    else if ( HasFlag( wxFRAME_DRAWER ) )
+    {
+        wclass = kDrawerWindowClass;
+        // Should this be left for compositing check below?
+        // CreateNewWindow will fail without it, should wxDrawerWindow turn
+        // on compositing before calling MacCreateRealWindow?
+        attr |= kWindowCompositingAttribute;// | kWindowStandardHandlerAttribute;
+    }
+#endif  //10.2 and up
     else
     {
         if ( HasFlag( wxMINIMIZE_BOX ) || HasFlag( wxMAXIMIZE_BOX ) ||
@@ -989,17 +1108,17 @@ void  wxTopLevelWindowMac::MacCreateRealWindow( const wxString& title,
     // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of 
     // the content view, so we have to retrieve it explicitely
     HIViewFindByID( HIViewGetRoot( (WindowRef) m_macWindow ) , kHIViewWindowContentID , 
-        *m_peer ) ;
+        m_peer->GetControlRefAddr() ) ;
     if ( !m_peer->Ok() )
     {
         // compatibility mode fallback
-        GetRootControl( (WindowRef) m_macWindow , *m_peer ) ;
+        GetRootControl( (WindowRef) m_macWindow , m_peer->GetControlRefAddr() ) ;
     }
 #else
-    ::CreateRootControl( (WindowRef)m_macWindow , *m_peer ) ;
+    ::CreateRootControl( (WindowRef)m_macWindow , m_peer->GetControlRefAddr() ) ;
 #endif
     // the root control level handleer
-    MacInstallEventHandler() ;
+    MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ) ;
 
     // the frame window event handler
     InstallStandardEventHandler( GetWindowEventTarget(MAC_WXHWND(m_macWindow)) ) ;
@@ -1103,6 +1222,72 @@ bool wxTopLevelWindowMac::Show(bool show)
     return TRUE ;
 }
 
+bool wxTopLevelWindowMac::ShowFullScreen(bool show, long style)
+{    
+    if ( show )
+    {
+        FullScreenData *data = (FullScreenData *)m_macFullScreenData ;
+        delete data ;
+        data = new FullScreenData() ;
+        
+        m_macFullScreenData = data ;
+        data->m_position = GetPosition() ;
+        data->m_size = GetSize() ;
+        
+        if ( style & wxFULLSCREEN_NOMENUBAR )
+        {
+                HideMenuBar() ;
+        }
+        int left , top , right , bottom ;
+        wxRect client = wxGetClientDisplayRect() ;
+
+        int x, y, w, h ;
+        
+        x = client.x ;
+        y = client.y ;
+        w = client.width ;
+        h = client.height ;
+        
+        MacGetContentAreaInset( left , top , right , bottom ) ;
+
+        if ( style & wxFULLSCREEN_NOCAPTION )
+        {
+            y -= top ;
+            h += top ;
+        }
+        if ( style & wxFULLSCREEN_NOBORDER )
+        {
+            x -= left ;
+            w += left + right ;
+            h += bottom ;
+        }
+        if ( style & wxFULLSCREEN_NOTOOLBAR )
+        {
+            // TODO
+        }
+        if ( style & wxFULLSCREEN_NOSTATUSBAR )
+        {
+            // TODO
+        }
+        SetSize( x , y , w, h ) ;
+    }
+    else
+    {
+        ShowMenuBar() ;
+        FullScreenData *data = (FullScreenData *) m_macFullScreenData ;
+        SetPosition( data->m_position ) ;
+        SetSize( data->m_size ) ;
+        delete data ;
+        m_macFullScreenData = NULL ;
+    }
+    return FALSE; 
+}
+
+bool wxTopLevelWindowMac::IsFullScreen() const 
+{ 
+    return m_macFullScreenData != NULL ; 
+}
+
 // we are still using coordinates of the content view, todo switch to structure bounds
 
 void wxTopLevelWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
@@ -1249,7 +1434,7 @@ static SInt32 wxShapedMacWindowGetFeatures(WindowRef window, SInt32 param)
                         kWindowCanDrawInCurrentPort|
                         //kWindowCanMeasureTitle|
                         kWindowWantsDisposeAtProcessDeath|
-                        kWindowSupportsSetGrowImageRegion|
+                        kWindowSupportsGetGrowImageRegion|
                         kWindowDefSupportsColorGrafPort;
     return 1;
 }