]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/window.cpp
Query value from the model column given by col->GetModelColumn()
[wxWidgets.git] / src / mac / carbon / window.cpp
index 9e1334d4ce17c247cafe0b10a379829bd0fc02f7..aa9503fb3b78b666319df01438c84b5cbcaba42d 100644 (file)
@@ -171,6 +171,8 @@ static const EventTypeSpec eventList[] =
 static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
 {
     OSStatus result = eventNotHandledErr ;
+    static wxWindowMac* targetFocusWindow = NULL;
+    static wxWindowMac* formerFocusWindow = NULL;
 
     wxMacCarbonEvent cEvent( event ) ;
 
@@ -209,7 +211,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
                 if ( thisWindow->MacIsUserPane() )
                 {
                     static float color = 0.5 ;
-                    static channel = 0 ;
+                    static int channel = 0 ;
                     HIRect bounds;
                     CGContextRef cgContext = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef) ;
 
@@ -232,17 +234,21 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
                     bool created = false ;
                     CGContextRef cgContext = NULL ;
                     OSStatus err = cEvent.GetParameter<CGContextRef>(kEventParamCGContextRef, &cgContext) ;
-                    wxASSERT_MSG( err == noErr , wxT("Unable to retrieve CGContextRef") ) ;
+                    if ( err != noErr )
+                    {
+                        wxFAIL_MSG("Unable to retrieve CGContextRef");
+                    }
+
                     thisWindow->MacSetCGContextRef( cgContext ) ;
 
                     {
                         wxMacCGContextStateSaver sg( cgContext ) ;
-                        float alpha = 1.0 ;
+                        CGFloat alpha = (CGFloat)1.0 ;
                         {
                             wxWindow* iter = thisWindow ;
                             while ( iter )
                             {
-                                alpha *= (float) iter->GetTransparent()/255.0 ;
+                                alpha *= (CGFloat)( iter->GetTransparent()/255.0 ) ;
                                 if ( iter->IsTopLevel() )
                                     iter = NULL ;
                                 else
@@ -276,7 +282,13 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
             break ;
 
         case kEventControlVisibilityChanged :
-            thisWindow->MacVisibilityChanged() ;
+            // we might have two native controls attributed to the same wxWindow instance
+            // eg a scrollview and an embedded textview, make sure we only fire for the 'outer'
+            // control, as otherwise native and wx visibility are different
+            if ( thisWindow->GetPeer() != NULL && thisWindow->GetPeer()->GetControlRef() == controlRef )
+            {
+                thisWindow->MacVisibilityChanged() ;
+            }
             break ;
 
         case kEventControlEnabledStateChanged :
@@ -308,6 +320,11 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
         case kEventControlFocusPartChanged :
             // the event is emulated by wxmac for systems lower than 10.5
             {
+                if ( UMAGetSystemVersion() < 0x1050 )
+                {
+                    // as it is synthesized here, we have to manually avoid propagation
+                    result = noErr;
+                }
                 ControlPartCode previousControlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPreviousPart , typeControlPartCode );
                 ControlPartCode currentControlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlCurrentPart , typeControlPartCode );
 
@@ -334,8 +351,10 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
                         inKillFocusEvent = true ;
                         wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId());
                         event.SetEventObject(thisWindow);
+                        event.SetWindow(targetFocusWindow);
                         thisWindow->HandleWindowEvent(event) ;
                         inKillFocusEvent = false ;
+                        targetFocusWindow = NULL;
                     }
                 }
                 else if ( previousControlPart == 0 )
@@ -353,7 +372,9 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
 
                     wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId());
                     event.SetEventObject(thisWindow);
+                    event.SetWindow(formerFocusWindow);
                     thisWindow->HandleWindowEvent(event) ;
+                    formerFocusWindow = NULL;
                 }
             }
             break;
@@ -367,7 +388,17 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
                 }
 #endif
                 ControlPartCode controlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
-
+                if ( controlPart != kControlFocusNoPart )
+                {
+                    targetFocusWindow = thisWindow;
+                    wxLogTrace(_T("Focus"), _T("focus to be set(%p)"), wx_static_cast(void*, thisWindow));
+                }
+                else
+                {
+                    formerFocusWindow = thisWindow;
+                    wxLogTrace(_T("Focus"), _T("focus to be lost(%p)"), wx_static_cast(void*, thisWindow));
+                }
+                
                 ControlPartCode previousControlPart = 0;
                 verify_noerr( HIViewGetFocusPart(controlRef, &previousControlPart));
 
@@ -384,27 +415,31 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
                 {
 // set back to 0 if problems arise
 #if 1
-                    ControlPartCode currentControlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
-                    // synthesize the event focus changed event
-                    EventRef evRef = NULL ;
-
-                    OSStatus err = MacCreateEvent(
-                                         NULL , kEventClassControl , kEventControlFocusPartChanged , TicksToEventTime( TickCount() ) ,
-                                         kEventAttributeUserEvent , &evRef );
-                    verify_noerr( err );
-
-                    wxMacCarbonEvent iEvent( evRef ) ;
-                    iEvent.SetParameter<ControlRef>( kEventParamDirectObject , controlRef ) ;
-                    iEvent.SetParameter<ControlPartCode>( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart ) ;
-                    iEvent.SetParameter<ControlPartCode>( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart ) ;
-
-#if 0
-                    // TODO test this first, avoid double posts etc...
-                    PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh );
+                    if ( result == noErr )
+                    {
+                        ControlPartCode currentControlPart = cEvent.GetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode );
+                        // synthesize the event focus changed event
+                        EventRef evRef = NULL ;
+
+                        OSStatus err = MacCreateEvent(
+                                             NULL , kEventClassControl , kEventControlFocusPartChanged , TicksToEventTime( TickCount() ) ,
+                                             kEventAttributeUserEvent , &evRef );
+                        verify_noerr( err );
+
+                        wxMacCarbonEvent iEvent( evRef ) ;
+                        iEvent.SetParameter<ControlRef>( kEventParamDirectObject , controlRef );
+                        iEvent.SetParameter<EventTargetRef>( kEventParamPostTarget, typeEventTargetRef, GetControlEventTarget( controlRef ) );
+                        iEvent.SetParameter<ControlPartCode>( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart );
+                        iEvent.SetParameter<ControlPartCode>( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart );
+        
+#if 1
+                        // TODO test this first, avoid double posts etc...
+                        PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh );
 #else
-                    wxMacWindowControlEventHandler( NULL , evRef , data ) ;
+                        wxMacWindowControlEventHandler( NULL , evRef , data ) ;
 #endif
-                    ReleaseEvent( evRef ) ;
+                        ReleaseEvent( evRef ) ;
+                    }
 #else
                     // old implementation, to be removed if the new one works
                     if ( controlPart == kControlFocusNoPart )
@@ -879,9 +914,6 @@ void wxWindowMac::Init()
     m_macIsUserPane = true;
     m_clipChildren = false ;
     m_cachedClippedRectValid = false ;
-
-    // we need a valid font for the encodings
-    wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
 }
 
 wxWindowMac::~wxWindowMac()
@@ -1108,7 +1140,7 @@ void wxWindowMac::MacUpdateControlFont()
 {
     m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
     // do not trigger refreshes upon invisible and possible partly created objects
-    if ( MacIsReallyShown() )
+    if ( IsShownOnScreen() )
         Refresh() ;
 }
 
@@ -1174,9 +1206,14 @@ void wxWindowMac::SetFocus()
 
     // as we cannot rely on the control features to find out whether we are in full keyboard mode,
     // we can only leave in case of an error
+    wxLogTrace(_T("Focus"), _T("before wxWindow::SetFocus(%p) %d"), wx_static_cast(void*, this), GetName().c_str());
     OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ;
     if ( err == errCouldntSetFocus )
+    {
+        wxLogTrace(_T("Focus"), _T("in wxWindow::SetFocus(%p) errCouldntSetFocus"), wx_static_cast(void*, this));
         return ;
+    }
+    wxLogTrace(_T("Focus"), _T("after wxWindow::SetFocus(%p)"), wx_static_cast(void*, this));
 
     SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() );
 }
@@ -1399,7 +1436,7 @@ void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
 
     if ( !IsTopLevel() )
     {
-        wxTopLevelWindowMac* top = MacGetTopLevelWindow();
+        wxNonOwnedWindow* top = MacGetTopLevelWindow();
         if (top)
         {
             pt.x -= MacGetLeftBorderSize() ;
@@ -1442,7 +1479,7 @@ void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
 
     if ( !IsTopLevel() )
     {
-        wxTopLevelWindowMac* top = MacGetTopLevelWindow();
+        wxNonOwnedWindow* top = MacGetTopLevelWindow();
         if (top)
         {
             wxMacControl::Convert( &pt , top->m_peer , m_peer ) ;
@@ -1573,7 +1610,7 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor)
 
     wxWindowMac *mouseWin = 0 ;
     {
-        wxTopLevelWindowMac *tlw = MacGetTopLevelWindow() ;
+        wxNonOwnedWindow *tlw = MacGetTopLevelWindow() ;
         WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ;
 
         ControlPartCode part ;
@@ -1673,7 +1710,7 @@ void wxWindowMac::MacInvalidateBorders()
     if ( m_peer == NULL )
         return ;
 
-    bool vis = MacIsReallyShown() ;
+    bool vis = IsShownOnScreen() ;
     if ( !vis )
         return ;
 
@@ -1942,7 +1979,7 @@ void wxWindowMac::SetLabel(const wxString& title)
         m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ;
 
     // do not trigger refreshes upon invisible and possible partly created objects
-    if ( MacIsReallyShown() )
+    if ( IsShownOnScreen() )
         Refresh() ;
 }
 
@@ -1988,31 +2025,6 @@ void wxWindowMac::MacEnabledStateChanged()
 // status queries on the inherited window's state
 //
 
-bool wxWindowMac::MacIsReallyShown()
-{
-    // only under OSX the visibility of the TLW is taken into account
-    if ( m_isBeingDeleted )
-        return false ;
-
-#if TARGET_API_MAC_OSX
-    if ( m_peer && m_peer->Ok() )
-        return m_peer->IsVisible();
-#endif
-
-    wxWindow* win = this ;
-    while ( win->IsShown() )
-    {
-        if ( win->IsTopLevel() )
-            return true ;
-
-        win = win->GetParent() ;
-        if ( win == NULL )
-            return true ;
-    }
-
-    return false ;
-}
-
 bool wxWindowMac::MacIsReallyEnabled()
 {
     return m_peer->IsEnabled() ;
@@ -2048,8 +2060,12 @@ void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y,
                            int *descent, int *externalLeading, const wxFont *theFont ) const
 {
     const wxFont *fontToUse = theFont;
+    wxFont tempFont;
     if ( !fontToUse )
-        fontToUse = &m_font;
+    {
+        tempFont = GetFont();
+        fontToUse = &tempFont;
+    }
 
     wxClientDC dc( (wxWindowMac*) this ) ;
     wxCoord lx,ly,ld,le ;
@@ -2074,7 +2090,7 @@ void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect)
     if ( m_peer == NULL )
         return ;
 
-    if ( !MacIsReallyShown() )
+    if ( !IsShownOnScreen() )
         return ;
 
     if ( rect )
@@ -2137,6 +2153,12 @@ void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
     {
         event.GetDC()->Clear() ;
     }
+    else if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM )
+    {
+        // don't skip the event here, custom background means that the app
+        // is drawing it itself in its OnPaint(), so don't draw it at all
+        // now to avoid flicker
+    }
     else
     {
         event.Skip() ;
@@ -2263,7 +2285,7 @@ void  wxWindowMac::MacPaintGrowBox()
         }
         else
         {
-            CGContextSetRGBFillColor( cgContext, 1.0, 1.0 , 1.0 , 1.0 );
+            CGContextSetRGBFillColor( cgContext, (CGFloat) 1.0, (CGFloat)1.0 ,(CGFloat) 1.0 , (CGFloat)1.0 );
         }
         CGContextFillRect( cgContext, cgrect );
         CGContextRestoreGState( cgContext );
@@ -2574,14 +2596,14 @@ void wxWindowMac::ClearBackground()
 
 void wxWindowMac::Update()
 {
-    wxTopLevelWindowMac* top = MacGetTopLevelWindow();
+    wxNonOwnedWindow* top = MacGetTopLevelWindow();
     if (top)
         top->MacPerformUpdates() ;
 }
 
-wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
+wxNonOwnedWindow* wxWindowMac::MacGetTopLevelWindow() const
 {
-    wxTopLevelWindowMac* win = NULL ;
+    wxNonOwnedWindow* win = NULL ;
     WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ;
     if ( window )
         win = wxFindWinFromMacWindow( window ) ;
@@ -2614,7 +2636,7 @@ const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
 {
     static wxRegion emptyrgn ;
 
-    if ( !m_isBeingDeleted && MacIsReallyShown() /*m_peer->IsVisible() */ )
+    if ( !m_isBeingDeleted && IsShownOnScreen() )
     {
         MacUpdateClippedRects() ;
         if ( includeOuterStructures )
@@ -2832,7 +2854,7 @@ WXWindow wxWindowMac::MacGetTopLevelWindowRef() const
 #if wxUSE_POPUPWIN
             wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow);
             if ( popupwin )
-                return popupwin->MacGetPopupWindowRef();
+                return popupwin->MacGetWindowRef();
 #endif
         }
         iter = iter->GetParent() ;
@@ -3153,11 +3175,15 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event )
 
 void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) )
 {
-    if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL
-         && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT )
-        CallNextEventHandler(
-            (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() ,
-            (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
+    // for native controls: call their native paint method
+    if ( !MacIsUserPane() || ( IsTopLevel() && GetBackgroundStyle() == wxBG_STYLE_SYSTEM ) )
+    {
+        if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL
+             && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT )
+            CallNextEventHandler(
+                (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() ,
+                (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
+    }
 }
 
 void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control),
@@ -3222,5 +3248,26 @@ wxByte wxWindowMac::GetTransparent() const
 
 bool wxWindowMac::IsShownOnScreen() const
 {
-    return ((wxWindowMac*)this)->MacIsReallyShown();
+#if TARGET_API_MAC_OSX
+    if ( m_peer && m_peer->Ok() )
+    {
+        bool peerVis = m_peer->IsVisible();
+        bool wxVis = wxWindowBase::IsShownOnScreen();
+        if( peerVis != wxVis )
+        {
+            // CS : put a breakpoint here to investigate differences
+            // between native an wx visibilities
+            // the only place where I've encountered them until now
+            // are the hiding/showing sequences where the vis-changed event is
+            // first sent to the innermost control, while wx does things
+            // from the outmost control
+            wxVis = wxWindowBase::IsShownOnScreen();
+            return wxVis;
+        }
+
+        return m_peer->IsVisible();
+    }
+#endif
+
+    return wxWindowBase::IsShownOnScreen();
 }