]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/window.cpp
wxSYS_COLOUR_WINDOW is better for window backgrounds on PPC/Smartphone
[wxWidgets.git] / src / mac / carbon / window.cpp
index 0f361b6d1ed1e42926710ad9fb1ecf3c4036afa3..8b6475a926ecb1dac73221d473ea71b5abf7ff1e 100644 (file)
@@ -222,6 +222,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
                 {
                     if ( thisWindow->GetPeer()->IsCompositing() == false )
                     {
+/*
                         if ( thisWindow->GetPeer()->IsRootControl() == false )
                         {
                             GetControlBounds( thisWindow->GetPeer()->GetControlRef() , &controlBounds ) ;
@@ -230,6 +231,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl
                         {
                             thisWindow->GetPeer()->GetRect( &controlBounds ) ;
                         }
+*/ 
                         allocatedRgn = NewRgn() ;
                         CopyRgn( updateRgn , allocatedRgn ) ;
                         OffsetRgn( allocatedRgn , -controlBounds.left , -controlBounds.top ) ;
@@ -748,6 +750,8 @@ void wxWindowMac::Init()
 #if wxMAC_USE_CORE_GRAPHICS
     m_cgContextRef = NULL ;
 #endif
+    m_clipChildren = false ;
+    m_cachedClippedRectValid = false ;
     // we need a valid font for the encodings
     wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
 }
@@ -1115,17 +1119,17 @@ void wxWindowMac::SetFocus()
 
 void wxWindowMac::DoCaptureMouse()
 {
-    wxTheApp->s_captureWindow = this ;
+    wxApp::s_captureWindow = this ;
 }
 
 wxWindow* wxWindowBase::GetCapture()
 {
-    return wxTheApp->s_captureWindow ;
+    return wxApp::s_captureWindow ;
 }
 
 void wxWindowMac::DoReleaseMouse()
 {
-    wxTheApp->s_captureWindow = NULL ;
+    wxApp::s_captureWindow = NULL ;
 }
 
 #if    wxUSE_DRAG_AND_DROP
@@ -1341,9 +1345,13 @@ void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
 
     if ( !IsTopLevel() )
     {
-        wxMacControl::Convert( &pt , MacGetTopLevelWindow()->m_peer , m_peer ) ;
-        pt.x += MacGetLeftBorderSize() ;
-        pt.y += MacGetTopBorderSize() ;
+        wxTopLevelWindowMac* top = MacGetTopLevelWindow();
+        if (top)
+        {
+            wxMacControl::Convert( &pt , top->m_peer , m_peer ) ;
+            pt.x += MacGetLeftBorderSize() ;
+            pt.y += MacGetTopBorderSize() ;
+        }
     }
 
     if ( x ) *x = (int) pt.x ;
@@ -1432,11 +1440,11 @@ void wxWindowMac::DoGetClientSize(int *x, int *y) const
 
     if (m_hScrollBar  && m_hScrollBar->IsShown() )
     {
-        hh -= m_hScrollBar->GetSize().y ; // MAC_SCROLLBAR_SIZE ;
+        hh -= m_hScrollBar->GetSize().y ;
     }
     if (m_vScrollBar  && m_vScrollBar->IsShown() )
     {
-        ww -= m_vScrollBar->GetSize().x ; // MAC_SCROLLBAR_SIZE;
+        ww -= m_vScrollBar->GetSize().x ;
     }
     if(x)   *x = ww;
     if(y)   *y = hh;
@@ -1741,10 +1749,10 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height)
 
         MacInvalidateBorders() ;
         
+        m_cachedClippedRectValid = false ;
         m_peer->SetRect( &r ) ;
-
-        if ( doMove )
-            wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
+        
+        wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified
 
         MacInvalidateBorders() ;
 
@@ -2405,12 +2413,11 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
     if( dx == 0 && dy ==0 )
         return ;
 
-
-    {
-
         int width , height ;
         GetClientSize( &width , &height ) ;
 #if TARGET_API_MAC_OSX
+       if ( 1 /* m_peer->IsCompositing() */ )
+       {
         // note there currently is a bug in OSX which makes inefficient refreshes in case an entire control
         // area is scrolled, this does not occur if width and height are 2 pixels less,
         // TODO write optimal workaround
@@ -2428,16 +2435,39 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
             m_peer->SetNeedsDisplay() ;
 #else
             // this would be the preferred version for fast drawing controls
-            if( UMAGetSystemVersion() < 0x1030 )
-                Update() ;
-            else
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
+            if( UMAGetSystemVersion() >= 0x1030 && m_peer->IsCompositing() )
                 HIViewRender(m_peer->GetControlRef()) ;
+            else
+#endif
+                Update() ;
 #endif
         }
         // as the native control might be not a 0/0 wx window coordinates, we have to offset
         scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ;
-        m_peer->ScrollRect( scrollrect , dx , dy ) ;
+        m_peer->ScrollRect( (&scrollrect) , dx , dy ) ;
+
+        // becuase HIViewScrollRect does not scroll the already invalidated area we have two options
+        // either immediate redraw or full invalidate
+#if 0
+        // is the better overall solution, as it does not slow down scrolling
+        m_peer->SetNeedsDisplay() ;
 #else
+        // this would be the preferred version for fast drawing controls       
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
+            if( UMAGetSystemVersion() >= 0x1030 && m_peer->IsCompositing() )
+                HIViewRender(m_peer->GetControlRef()) ;
+            else
+#endif
+                Update() ;
+
+#endif
+       }
+       else
+#endif
+       {
 
         wxPoint pos;
         pos.x = pos.y = 0;
@@ -2449,9 +2479,9 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
             wxClientDC dc(this) ;
             wxMacPortSetter helper(&dc) ;
 
-            m_peer->GetRect( &scrollrect ) ;
-            scrollrect.top += MacGetTopBorderSize() ;
-            scrollrect.left += MacGetLeftBorderSize() ;
+            m_peer->GetRectInWindowCoords( &scrollrect ) ;
+            //scrollrect.top += MacGetTopBorderSize() ;
+            //scrollrect.left += MacGetLeftBorderSize() ;
             scrollrect.bottom = scrollrect.top + height ;
             scrollrect.right = scrollrect.left + width ;
 
@@ -2485,7 +2515,7 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect)
             DisposeRgn( formerUpdateRgn ) ;
             DisposeRgn( scrollRgn ) ;
         }
-#endif
+        Update() ;
     }
 
     for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext())
@@ -2687,39 +2717,7 @@ void wxWindowMac::ClearBackground()
 void wxWindowMac::Update()
 {
 #if TARGET_API_MAC_OSX
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
-    WindowRef window = (WindowRef)MacGetTopLevelWindowRef() ;
-
-    // for composited windows this also triggers a redraw of all
-    // invalid views in the window
-    if( UMAGetSystemVersion() >= 0x1030 )
-        HIWindowFlush(window) ;
-    else
-#endif
-    {
-        // the only way to trigger the redrawing on earlier systems is to call
-        // ReceiveNextEvent
-
-        EventRef currentEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ;
-        UInt32 currentEventClass = 0 ;
-        UInt32 currentEventKind = 0 ;
-        if ( currentEvent != NULL )
-        {
-            currentEventClass = ::GetEventClass( currentEvent ) ;
-            currentEventKind = ::GetEventKind( currentEvent ) ;
-        }
-        if ( currentEventClass != kEventClassMenu )
-        {
-            // when tracking a menu, strange redraw errors occur if we flush now, so leave..
-
-            EventRef theEvent;
-            OSStatus status = noErr ;
-            status = ReceiveNextEvent( 0 , NULL , kEventDurationNoWait , false , &theEvent ) ;
-        }
-        else
-            m_peer->SetNeedsDisplay() ;
-    }
+       MacGetTopLevelWindow()->MacPerformUpdates() ;
 #else
     ::Draw1Control( m_peer->GetControlRef() ) ;
 #endif
@@ -2735,82 +2733,127 @@ wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const
     }
     return win ;
 }
-wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
+
+const wxRect& wxWindowMac::MacGetClippedClientRect() const 
+{
+    MacUpdateClippedRects() ;
+    return m_cachedClippedClientRect ;
+}
+
+const wxRect& wxWindowMac::MacGetClippedRect() const 
+{
+    MacUpdateClippedRects() ;
+    return m_cachedClippedRect ;
+}
+
+const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const 
 {
+    MacUpdateClippedRects() ;
+    return m_cachedClippedRectWithOuterStructure ;
+}
+
+const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures )
+{
+    static wxRegion emptyrgn ;
+    if ( !m_isBeingDeleted && MacIsReallyShown() /*m_peer->IsVisible() */ )
+    {
+        MacUpdateClippedRects() ;
+        if ( includeOuterStructures )
+            return m_cachedClippedRegionWithOuterStructure ;
+        else
+            return m_cachedClippedRegion ;
+    }
+    else
+    {
+        return emptyrgn ;
+    }
+}
+
+void wxWindowMac::MacUpdateClippedRects() const
+{
+    if ( m_cachedClippedRectValid )
+        return ;
+
     // 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() ;
-    if ( !m_isBeingDeleted && MacIsReallyShown() /*m_peer->IsVisible() */ )
+    Rect rIncludingOuterStructures ;
+    
+    m_peer->GetRect( &r ) ;
+    r.left -= MacGetLeftBorderSize() ;
+    r.top -= MacGetTopBorderSize() ;
+    r.bottom += MacGetBottomBorderSize() ;
+    r.right += MacGetRightBorderSize() ;
+
+    r.right -= r.left ;
+    r.bottom -= r.top ;
+    r.left = 0 ;
+    r.top = 0 ;
+
+    rIncludingOuterStructures = r ;
+    InsetRect( &rIncludingOuterStructures , -4 , -4 ) ;
+    
+    wxRect cl = GetClientRect() ;
+    Rect rClient = { cl.y , cl.x , cl.y + cl.height , cl.x + cl.width } ;
+    
+    const wxWindow* child = this ;
+    const wxWindow* parent = NULL ;
+    while( !child->IsTopLevel() && ( parent = child->GetParent() ) != NULL )
     {
-        m_peer->GetRect( &r ) ;
-        r.left -= MacGetLeftBorderSize() ;
-        r.top -= MacGetTopBorderSize() ;
-        r.bottom += MacGetBottomBorderSize() ;
-        r.right += MacGetRightBorderSize() ;
+        int x , y ;
+        wxSize size ;
 
-        r.right -= r.left ;
-        r.bottom -= r.top ;
-        r.left = 0 ;
-        r.top = 0 ;
+        if ( parent->MacIsChildOfClientArea(child) )
+        {
+            size = parent->GetClientSize() ;
+            wxPoint origin = parent->GetClientAreaOrigin() ;
+            x = origin.x ;
+            y = origin.y ;
+        }
+        else
+        {
+            // this will be true for scrollbars, toolbars etc.
+            size = parent->GetSize() ;
+            y = parent->MacGetTopBorderSize() ;
+            x = parent->MacGetLeftBorderSize() ;
+            size.x -= parent->MacGetLeftBorderSize() + parent->MacGetRightBorderSize() ;
+            size.y -= parent->MacGetTopBorderSize() + parent->MacGetBottomBorderSize() ;
+        }
 
-        if ( includeOuterStructures )
-            InsetRect( &r , -4 , -4 ) ;
-        RectRgn( visRgn , &r ) ;
+        parent->MacWindowToRootWindow( &x, &y ) ;
+        MacRootWindowToWindow( &x , &y ) ;
 
-        if ( !IsTopLevel() )
-        {
-            wxWindow* child = this ;
-            wxWindow* parent = child->GetParent() ;
-            while( parent )
-            {
-                int x , y ;
-                wxSize size ;
-                // we have to find a better clipping algorithm here, in order not to clip things
-                // positioned like status and toolbar
-                if ( 1 /* parent->IsTopLevel() && child->IsKindOf( CLASSINFO( wxToolBar ) ) */ )
-                {
-                    size = parent->GetSize() ;
-                    x = y = 0 ;
-                }
-                else
-                {
-                    size = parent->GetClientSize() ;
-                    wxPoint origin = parent->GetClientAreaOrigin() ;
-                    x = origin.x ;
-                    y = origin.y ;
-                }
-                parent->MacWindowToRootWindow( &x, &y ) ;
-                MacRootWindowToWindow( &x , &y ) ;
+        Rect rparent = { y , x , y + size.y , x + size.x } ;
 
-                if ( !includeOuterStructures || (
-                    parent->MacClipChildren() ||
-                    ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() )
-                    ) )
-                {
-                    SetRectRgn( tempRgn ,
-                        x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() ,
-                        x + size.x - parent->MacGetRightBorderSize(),
-                        y + size.y - parent->MacGetBottomBorderSize()) ;
+        // the wxwindow and client rects will always be clipped
+        SectRect( &r , &rparent , &r ) ;
+        SectRect( &rClient , &rparent , &rClient ) ;
 
-                    SectRgn( visRgn , tempRgn , visRgn ) ;
-                }
-                if ( parent->IsTopLevel() )
-                    break ;
-                child = parent ;
-                parent = child->GetParent() ;
-            }
+        // the structure only at 'hard' borders
+        if ( parent->MacClipChildren() ||
+            ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) )
+        {
+            SectRect( &rIncludingOuterStructures , &rparent , &rIncludingOuterStructures ) ;
         }
+        child = parent ;
     }
-
-    wxRegion vis = visRgn ;
-    DisposeRgn( visRgn ) ;
-    DisposeRgn( tempRgn ) ;
-    return vis ;
+    
+    m_cachedClippedRect = wxRect( r.left , r.top , r.right - r.left , r.bottom - r.top ) ;
+    m_cachedClippedClientRect = wxRect( rClient.left , rClient.top , 
+        rClient.right - rClient.left , rClient.bottom - rClient.top ) ;
+    m_cachedClippedRectWithOuterStructure = wxRect( 
+        rIncludingOuterStructures.left , rIncludingOuterStructures.top , 
+        rIncludingOuterStructures.right - rIncludingOuterStructures.left , 
+        rIncludingOuterStructures.bottom - rIncludingOuterStructures.top ) ;
+    
+    m_cachedClippedRegionWithOuterStructure = wxRegion( m_cachedClippedRectWithOuterStructure ) ;
+    m_cachedClippedRegion = wxRegion( m_cachedClippedRect ) ;
+    m_cachedClippedClientRegion = wxRegion( m_cachedClippedClientRect ) ;
+    
+    m_cachedClippedRectValid = true ;
 }
 
 /*
@@ -2839,12 +2882,12 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time )
             // for all the others only their client area, otherwise they
             // might be drawing with full alpha and eg put blue into
             // the grow-box area of a scrolled window (scroll sample)
-            wxDC* dc ;
+            wxDC* dc = new wxWindowDC(this);
             if ( IsTopLevel() )
-                dc = new wxWindowDC(this);
+                dc->SetClippingRegion(wxRegion(updatergn));
             else
-                dc = new wxClientDC(this);
-            dc->SetClippingRegion(wxRegion(updatergn));
+                dc->SetClippingRegion(wxRegion(newupdate));
+                
             wxEraseEvent eevent( GetId(), dc );
             eevent.SetEventObject( this );
             GetEventHandler()->ProcessEvent( eevent );
@@ -2978,6 +3021,14 @@ void wxWindowMac::MacCreateScrollBars( long style )
     MacRepositionScrollBars() ; // we might have a real position shift
 }
 
+bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const
+{
+    if ( child != NULL && ( child == m_hScrollBar || child == m_vScrollBar ) )
+        return false ;
+    else
+        return true ;
+}
+
 void wxWindowMac::MacRepositionScrollBars()
 {
     if ( !m_hScrollBar && !m_vScrollBar )
@@ -3064,6 +3115,7 @@ bool wxWindowMac::AcceptsFocus() const
 
 void wxWindowMac::MacSuperChangedPosition()
 {
+    m_cachedClippedRectValid = false ;
     // only window-absolute structures have to be moved i.e. controls
 
     wxWindowList::compatibility_iterator node = GetChildren().GetFirst();