]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/window.cpp
making tool enable consistent (was using mix of enable and activate controls before)
[wxWidgets.git] / src / mac / carbon / window.cpp
index ecbedd6c887d611a161b16f5b1f644540efa9f17..ba16258f5366dd2a637565d34efe79efa8a1a465 100644 (file)
@@ -24,6 +24,7 @@
 #include "wx/layout.h"
 #include "wx/dialog.h"
 #include "wx/scrolbar.h"
 #include "wx/layout.h"
 #include "wx/dialog.h"
 #include "wx/scrolbar.h"
+#include "wx/scrolwin.h"
 #include "wx/statbox.h"
 #include "wx/button.h"
 #include "wx/settings.h"
 #include "wx/statbox.h"
 #include "wx/button.h"
 #include "wx/settings.h"
@@ -36,6 +37,8 @@
 #include "wx/log.h"
 #include "wx/geometry.h"
 #include "wx/textctrl.h"
 #include "wx/log.h"
 #include "wx/geometry.h"
 #include "wx/textctrl.h"
+#include "wx/laywin.h"
+#include "wx/splitter.h"
 
 #include "wx/toolbar.h"
 #include "wx/dc.h"
 
 #include "wx/toolbar.h"
 #include "wx/dc.h"
@@ -387,6 +390,9 @@ static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handl
 
 pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
 {
 
 pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data )
 {
+    EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ;
+    EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ;
+    wxTheApp->MacSetCurrentEvent( event , handler ) ;
     OSStatus result = eventNotHandledErr ;
 
     switch ( GetEventClass( event ) )
     OSStatus result = eventNotHandledErr ;
 
     switch ( GetEventClass( event ) )
@@ -399,6 +405,7 @@ pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef
         default :
             break ;
     }
         default :
             break ;
     }
+    wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ;
     return result ;
 }
 
     return result ;
 }
 
@@ -981,9 +988,11 @@ void wxWindowMac::SetFocus()
 {
     if ( AcceptsFocus() )
     {
 {
     if ( AcceptsFocus() )
     {
-#if !TARGET_API_MAC_OSX
+
         wxWindow* former = FindFocus() ;
         wxWindow* former = FindFocus() ;
-#endif
+        if ( former == this )
+            return ;
+
         OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ;
         // 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
         OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ;
         // 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
@@ -1599,10 +1608,50 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
         }
 #endif
         bool vis = m_peer->IsVisible();
         }
 #endif
         bool vis = m_peer->IsVisible();
+    
+        int outerBorder = MacGetLeftBorderSize() ;
+        if ( m_peer->NeedsFocusRect() && m_peer->HasFocus() )
+            outerBorder = 4 ;         
+
+        if ( vis && ( outerBorder > 0 ) )
+        {
+            // as the borders are drawn on the parent we have to properly invalidate all these areas
+            RgnHandle updateInner = NewRgn() , updateOuter = NewRgn() , updateTotal = NewRgn() ;
+            
+            Rect rect ;
+
+            m_peer->GetRect( &rect ) ;
+            RectRgn( updateInner , &rect ) ;
+            InsetRect( &rect , -outerBorder , -outerBorder ) ;
+            RectRgn( updateOuter , &rect ) ;
+            DiffRgn( updateOuter , updateInner ,updateOuter ) ;
+            wxPoint parent(0,0); 
+            GetParent()->MacWindowToRootWindow( &parent.x , &parent.y ) ;
+            parent -= GetParent()->GetClientAreaOrigin() ;
+            OffsetRgn( updateOuter , -parent.x , -parent.y ) ;
+            CopyRgn( updateOuter , updateTotal ) ; 
+    
+            rect = r ;
+            RectRgn( updateInner , &rect ) ;
+            InsetRect( &rect , -outerBorder , -outerBorder ) ;
+            RectRgn( updateOuter , &rect ) ;
+            DiffRgn( updateOuter , updateInner ,updateOuter ) ;
+            wxPoint parentorig(0,0); 
+            GetParent()->MacWindowToRootWindow( &parentorig.x , &parentorig.y ) ;
+            parent -= GetParent()->GetClientAreaOrigin() ;
+            OffsetRgn( updateOuter , -parentorig.x , -parentorig.y ) ;
+            UnionRgn( updateOuter , updateTotal , updateTotal ) ; 
+
+            GetParent()->m_peer->SetNeedsDisplay( true , updateTotal ) ;
+            DisposeRgn(updateOuter) ;
+            DisposeRgn(updateInner) ;
+            DisposeRgn(updateTotal) ;
+        }
 
         // the HIViewSetFrame call itself should invalidate the areas, but when testing with the UnicodeTextCtrl it does not !
         if ( vis )
             m_peer->SetVisibility( false , true ) ;
 
         // the HIViewSetFrame call itself should invalidate the areas, but when testing with the UnicodeTextCtrl it does not !
         if ( vis )
             m_peer->SetVisibility( false , true ) ;
+
         m_peer->SetRect( &r ) ; 
         if ( vis )
             m_peer->SetVisibility( true , true ) ;
         m_peer->SetRect( &r ) ; 
         if ( vis )
             m_peer->SetVisibility( true , true ) ;
@@ -2125,10 +2174,7 @@ void wxWindowMac::OnEraseBackground(wxEraseEvent& event)
 
 void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
 {
 
 void wxWindowMac::OnNcPaint( wxNcPaintEvent& event )
 {
-    wxWindowDC dc(this) ;
-    wxMacPortSetter helper(&dc) ;
-
-    MacPaintBorders( dc.m_macLocalOrigin.x , dc.m_macLocalOrigin.y) ;
+    event.Skip() ;
 }
 
 int wxWindowMac::GetScrollPos(int orient) const
 }
 
 int wxWindowMac::GetScrollPos(int orient) const
@@ -2197,94 +2243,40 @@ void wxWindowMac::MacPaintBorders( int left , int top )
     if( IsTopLevel() )
         return ;
         
     if( IsTopLevel() )
         return ;
         
-    int major,minor;
-    wxGetOsVersion( &major, &minor );
-
-    RGBColor darkShadow = { 0x0000, 0x0000 , 0x0000 } ;
-    RGBColor lightShadow = { 0x4444, 0x4444 , 0x4444 } ;
-    // OS X has lighter border edges than classic:
-    if (major >= 10) 
-    {
-        darkShadow.red                 = 0x8E8E;
-        darkShadow.green       = 0x8E8E;
-        darkShadow.blue        = 0x8E8E;
-        lightShadow.red        = 0xBDBD;
-        lightShadow.green      = 0xBDBD;
-        lightShadow.blue       = 0xBDBD;
-       }
-    
-    PenNormal() ;
+    Rect rect ;
+    m_peer->GetRect( &rect ) ; 
+    InsetRect( &rect, -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
 
 
-    int w , h ;
-    GetSize( &w , &h ) ;
-    Rect rect = { top , left , h + top , w + left } ;
+    if ( !IsTopLevel() )
+    {
+        wxTopLevelWindowMac* top = MacGetTopLevelWindow();
+        if (top)
+        {
+            wxPoint pt(0,0) ;
+            wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ;
+            rect.left += pt.x ;
+            rect.right += pt.x ;
+            rect.top += pt.y ;
+            rect.bottom += pt.y ;
+        }
+    }
+    
     if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
     {
     if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) )
     {
-#if wxMAC_USE_THEME_BORDER
+        Rect srect = rect ;
         SInt32 border = 0 ;
         GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ;
         SInt32 border = 0 ;
         GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ;
-        InsetRect( &rect , border , border );
-        DrawThemeEditTextFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
-#else
-        RGBColor white = { 0xFFFF, 0xFFFF , 0xFFFF } ;
-        RGBColor face = { 0xDDDD, 0xDDDD , 0xDDDD } ;
-    
-        bool sunken = HasFlag( wxSUNKEN_BORDER ) ;
-        RGBForeColor( &face );
-        MoveTo( left + 0 , top + h - 2 );
-        LineTo( left + 0 , top + 0 );
-        LineTo( left + w - 2 , top + 0 );
-
-        MoveTo( left + 2 , top + h - 3 );
-        LineTo( left + w - 3 , top + h - 3 );
-        LineTo( left + w - 3 , top + 2 );
-
-        RGBForeColor( sunken ? &face : &darkShadow );
-        MoveTo( left + 0 , top + h - 1 );
-        LineTo( left + w - 1 , top + h - 1 );
-        LineTo( left + w - 1 , top + 0 );
-
-        RGBForeColor( sunken ? &lightShadow : &white );
-        MoveTo( left + 1 , top + h - 3 );
-        LineTo( left + 1, top + 1 );
-        LineTo( left + w - 3 , top + 1 );
-
-        RGBForeColor( sunken ? &white : &lightShadow );
-        MoveTo( left + 1 , top + h - 2 );
-        LineTo( left + w - 2 , top + h - 2 );
-        LineTo( left + w - 2 , top + 1 );
-
-        RGBForeColor( sunken ? &darkShadow : &face );
-        MoveTo( left + 2 , top + h - 4 );
-        LineTo( left + 2 , top + 2 );
-        LineTo( left + w - 4 , top + 2 );
-#endif
+        InsetRect( &srect , border , border );
+        DrawThemeEditTextFrame(&srect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;
     }
     else if (HasFlag(wxSIMPLE_BORDER))
     {
     }
     else if (HasFlag(wxSIMPLE_BORDER))
     {
-#if wxMAC_USE_THEME_BORDER
+        Rect srect = rect ;
         SInt32 border = 0 ;
         GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
         SInt32 border = 0 ;
         GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ;
-        InsetRect( &rect , border , border );
+        InsetRect( &srect , border , border );
         DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;   
         DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ;   
-#else
-        Rect rect = { top , left , h + top , w + left } ;
-        RGBForeColor( &darkShadow ) ;
-        FrameRect( &rect ) ;
-#endif
     }
     }
-
-    if ( MacGetTopLevelWindow() && m_peer->NeedsFocusRect() && m_peer->HasFocus() )
-    {
-        int w , h ;
-        int x , y ;
-        x = y = 0 ;
-        MacWindowToRootWindow( &x , &y ) ;
-        GetSize( &w , &h ) ;
-        Rect rect = {y , x , h + y , w + x } ;
-        DrawThemeFocusRect( &rect , true ) ;
-    }
-
 }
 
 void wxWindowMac::RemoveChild( wxWindowBase *child )
 }
 
 void wxWindowMac::RemoveChild( wxWindowBase *child )
@@ -2495,7 +2487,25 @@ void wxWindowMac::OnSetFocus(wxFocusEvent& event)
         if ( event.GetEventType() == wxEVT_SET_FOCUS )
             DrawThemeFocusRect( &rect , true ) ;
         else
         if ( event.GetEventType() == wxEVT_SET_FOCUS )
             DrawThemeFocusRect( &rect , true ) ;
         else
+        {
             DrawThemeFocusRect( &rect , false ) ;
             DrawThemeFocusRect( &rect , false ) ;
+            
+            // as this erases part of the frame we have to redraw borders
+            // and because our z-ordering is not always correct (staticboxes)
+            // we have to invalidate things, we cannot simple redraw
+            RgnHandle updateInner = NewRgn() , updateOuter = NewRgn() ;
+            RectRgn( updateInner , &rect ) ;
+            InsetRect( &rect , -4 , -4 ) ;
+            RectRgn( updateOuter , &rect ) ;
+            DiffRgn( updateOuter , updateInner ,updateOuter ) ;
+            wxPoint parent(0,0); 
+            GetParent()->MacWindowToRootWindow( &parent.x , &parent.y ) ;
+            parent -= GetParent()->GetClientAreaOrigin() ;
+            OffsetRgn( updateOuter , -parent.x , -parent.y ) ;
+            GetParent()->m_peer->SetNeedsDisplay( true , updateOuter ) ;
+            DisposeRgn(updateOuter) ;
+            DisposeRgn(updateInner) ;
+        }
     }
 
     event.Skip();
     }
 
     event.Skip();
@@ -2626,7 +2636,11 @@ wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
 }
 wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
 {
 }
 wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
 {
-
+    // includeOuterStructures is true if we try to draw somthing like a focus ring etc.
+    // also a window dc uses this, in this case we only clip in the hierarchy for hard
+    // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having
+    // to add focus borders everywhere
+    
     Rect r ;
     RgnHandle visRgn = NewRgn() ;
     RgnHandle tempRgn = NewRgn() ;
     Rect r ;
     RgnHandle visRgn = NewRgn() ;
     RgnHandle tempRgn = NewRgn() ;
@@ -2651,7 +2665,7 @@ wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
             r.top = 0 ;
         }
         if ( includeOuterStructures )
             r.top = 0 ;
         }
         if ( includeOuterStructures )
-            InsetRect( &r , -3 , -3 ) ;
+            InsetRect( &r , -4 , -4 ) ;
         RectRgn( visRgn , &r ) ;
 
         if ( !IsTopLevel() )
         RectRgn( visRgn , &r ) ;
 
         if ( !IsTopLevel() )
@@ -2679,12 +2693,19 @@ wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
                 parent->MacWindowToRootWindow( &x, &y ) ;
                 MacRootWindowToWindow( &x , &y ) ;
 
                 parent->MacWindowToRootWindow( &x, &y ) ;
                 MacRootWindowToWindow( &x , &y ) ;
 
-                SetRectRgn( tempRgn ,
-                    x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() ,
-                    x + size.x - parent->MacGetRightBorderSize(),
-                    y + size.y - parent->MacGetBottomBorderSize()) ;
+                if ( !includeOuterStructures || (
+                    parent->IsKindOf( CLASSINFO( wxScrolledWindow ) ) ||
+                    parent->IsKindOf( CLASSINFO( wxSashLayoutWindow ) ) ||
+                    ( parent->GetParent() && parent->GetParent()->IsKindOf( CLASSINFO( wxSplitterWindow ) ) )
+                    ) )
+                {
+                    SetRectRgn( tempRgn ,
+                        x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() ,
+                        x + size.x - parent->MacGetRightBorderSize(),
+                        y + size.y - parent->MacGetBottomBorderSize()) ;
 
 
-                SectRgn( visRgn , tempRgn , visRgn ) ;
+                    SectRgn( visRgn , tempRgn , visRgn ) ;
+                }
                 if ( parent->IsTopLevel() )
                     break ;
                 child = parent ;
                 if ( parent->IsTopLevel() )
                     break ;
                 child = parent ;
@@ -2738,12 +2759,25 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
             event.m_timeStamp = time ;
             event.SetEventObject(this);
             handled = GetEventHandler()->ProcessEvent(event); 
             event.m_timeStamp = time ;
             event.SetEventObject(this);
             handled = GetEventHandler()->ProcessEvent(event); 
+
+            // we have to call the default built-in handler, as otherwise our frames will be drawn and immediately erased afterwards
+            if ( !handled )
+            {
+                if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL )
+                {
+                    CallNextEventHandler((EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , (EventRef) wxTheApp->MacGetCurrentEvent() ) ;
+                    handled = true ;
+                }
+            }
+
         }
         
         // now we cannot rely on having its borders drawn by a window itself, as it does not
         // get the updateRgn wide enough to always do so, so we do it from the parent
         // this would also be the place to draw any custom backgrounds for native controls
         // in Composited windowing
         }
         
         // now we cannot rely on having its borders drawn by a window itself, as it does not
         // get the updateRgn wide enough to always do so, so we do it from the parent
         // this would also be the place to draw any custom backgrounds for native controls
         // in Composited windowing
+        wxPoint clientOrigin = GetClientAreaOrigin() ;
+        
         for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
         {
             wxWindowMac *child = node->GetData();
         for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext())
         {
             wxWindowMac *child = node->GetData();
@@ -2752,22 +2786,36 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
             if (child->IsTopLevel()) continue;
             if (!child->IsShown()) continue;
 
             if (child->IsTopLevel()) continue;
             if (!child->IsShown()) continue;
 
+            int x,y;
+            child->GetPosition( &x, &y );
+            int w,h;
+            child->GetSize( &w, &h );
+            Rect childRect = { y , x , y + h , x + w } ;
+            OffsetRect( &childRect , clientOrigin.x , clientOrigin.y ) ;
             if ( child->MacGetTopBorderSize() )
             {
             if ( child->MacGetTopBorderSize() )
             {
-                int x,y;
-                child->GetPosition( &x, &y );
-                int w,h;
-                child->GetSize( &w, &h );
-                Rect childRect = { y , x , y + h , x + w } ;
-                OffsetRect( &childRect , MacGetLeftBorderSize() , MacGetTopBorderSize() ) ;
                 if ( RectInRgn( &childRect , updatergn ) )
                 {
                     // paint custom borders
                     wxNcPaintEvent eventNc( child->GetId() );
                     eventNc.SetEventObject( child );
                 if ( RectInRgn( &childRect , updatergn ) )
                 {
                     // paint custom borders
                     wxNcPaintEvent eventNc( child->GetId() );
                     eventNc.SetEventObject( child );
-                    child->GetEventHandler()->ProcessEvent( eventNc );
+                    if ( !child->GetEventHandler()->ProcessEvent( eventNc ) )
+                    {
+                        wxWindowDC dc(this) ;
+                        dc.SetClippingRegion(wxRegion(updatergn));
+                        wxMacPortSetter helper(&dc) ;
+                        child->MacPaintBorders( dc.m_macLocalOrigin.x + childRect.left , dc.m_macLocalOrigin.y + childRect.top)  ;
+                    }
                 }
                 }
-            }     
+            } 
+            if ( child->m_peer->NeedsFocusRect() && child->m_peer->HasFocus() )
+            {
+                wxWindowDC dc(this) ;
+                dc.SetClippingRegion(wxRegion(updatergn));
+                wxMacPortSetter helper(&dc) ;
+                OffsetRect( &childRect , dc.m_macLocalOrigin.x , dc.m_macLocalOrigin.y ) ;
+                DrawThemeFocusRect( &childRect , true ) ;
+            }
         }
     }
     return handled ;
         }
     }
     return handled ;