X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1f1c8bd4d13ee2e1a6830c68770b7acdad7ca946..222702b112dcc7bebe018d6f4d66fe469fefd02c:/src/mac/carbon/window.cpp?ds=sidebyside diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index 3f681c8386..4bd0ab12be 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -76,8 +76,6 @@ extern wxList wxPendingDelete; IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) #endif // __WXUNIVERSAL__/__WXMAC__ -#if !USE_SHARED_LIBRARY - BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase) EVT_NC_PAINT(wxWindowMac::OnNcPaint) EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground) @@ -89,8 +87,6 @@ BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase) EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent) END_EVENT_TABLE() -#endif - #define wxMAC_DEBUG_REDRAW 0 #ifndef wxMAC_DEBUG_REDRAW #define wxMAC_DEBUG_REDRAW 0 @@ -201,23 +197,49 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl RgnHandle updateRgn = NULL ; RgnHandle allocatedRgn = NULL ; wxRegion visRegion = thisWindow->MacGetVisibleRegion() ; + Rect controlBounds ; + if ( thisWindow->GetPeer()->IsCompositing() == false ) + { + if ( thisWindow->GetPeer()->IsRootControl() == false ) + { + GetControlBounds( thisWindow->GetPeer()->GetControlRef() , &controlBounds ) ; + } + else + { + thisWindow->GetPeer()->GetRect( &controlBounds ) ; + } + } + if ( cEvent.GetParameter(kEventParamRgnHandle, &updateRgn) != noErr ) { updateRgn = (RgnHandle) visRegion.GetWXHRGN() ; } else { - if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 ) + if ( thisWindow->GetPeer()->IsCompositing() == false ) { - // as this update region is in native window locals we must adapt it to wx window local allocatedRgn = NewRgn() ; CopyRgn( updateRgn , allocatedRgn ) ; + OffsetRgn( allocatedRgn , -controlBounds.left , -controlBounds.top ) ; // hide the given region by the new region that must be shifted wxMacNativeToWindow( thisWindow , allocatedRgn ) ; updateRgn = allocatedRgn ; } + else + { + if ( thisWindow->MacGetLeftBorderSize() != 0 || thisWindow->MacGetTopBorderSize() != 0 ) + { + // as this update region is in native window locals we must adapt it to wx window local + allocatedRgn = NewRgn() ; + CopyRgn( updateRgn , allocatedRgn ) ; + // hide the given region by the new region that must be shifted + wxMacNativeToWindow( thisWindow , allocatedRgn ) ; + updateRgn = allocatedRgn ; + } + } } - + Rect rgnBounds ; + GetRegionBounds( updateRgn , &rgnBounds ) ; #if wxMAC_DEBUG_REDRAW if ( thisWindow->MacIsUserPane() ) { @@ -241,14 +263,52 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl #endif { #if wxMAC_USE_CORE_GRAPHICS - CGContextRef cgContext = cEvent.GetParameter(kEventParamCGContextRef) ; + bool created = false ; + CGContextRef cgContext = 0 ; + if ( cEvent.GetParameter(kEventParamCGContextRef, &cgContext) != noErr ) + { + wxASSERT( thisWindow->GetPeer()->IsCompositing() == false ) ; + + // this parameter is not provided on non-composited windows + created = true ; + // rest of the code expects this to be already transformed and clipped for local + CGrafPtr port = GetWindowPort( (WindowRef) thisWindow->MacGetTopLevelWindowRef() ) ; + Rect bounds ; + GetPortBounds( port , &bounds ) ; + CreateCGContextForPort( port , &cgContext ) ; + + wxMacWindowToNative( thisWindow , updateRgn ) ; + OffsetRgn( updateRgn , controlBounds.left , controlBounds.top ) ; + ClipCGContextToRegion( cgContext , &bounds , updateRgn ) ; + wxMacNativeToWindow( thisWindow , updateRgn ) ; + OffsetRgn( updateRgn , -controlBounds.left , -controlBounds.top ) ; + + CGContextTranslateCTM( cgContext , 0 , bounds.bottom - bounds.top ) ; + CGContextScaleCTM( cgContext , 1 , -1 ) ; + + CGContextTranslateCTM( cgContext , controlBounds.left , controlBounds.top ) ; + + /* + CGContextSetRGBFillColor( cgContext , 1.0 , 1.0 , 1.0 , 1.0 ) ; + CGContextFillRect(cgContext , CGRectMake( 0 , 0 , + controlBounds.right - controlBounds.left , + controlBounds.bottom - controlBounds.top ) ); + */ + + } thisWindow->MacSetCGContextRef( cgContext ) ; - wxMacCGContextStateSaver sg( cgContext ) ; + { + wxMacCGContextStateSaver sg( cgContext ) ; #endif - if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) ) - result = noErr ; + if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) ) + result = noErr ; #if wxMAC_USE_CORE_GRAPHICS - thisWindow->MacSetCGContextRef( NULL ) ; + thisWindow->MacSetCGContextRef( NULL ) ; + } + if ( created ) + { + CGContextRelease( cgContext ) ; + } #endif } if ( allocatedRgn ) @@ -411,6 +471,7 @@ pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef break ; case kEventClassService : result = wxMacWindowServiceEventHandler( handler, event , data ) ; + break ; default : break ; } @@ -502,6 +563,9 @@ void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part) { RgnHandle rgn = NewRgn() ; GetClip( rgn ) ; + int x = 0 , y = 0; + MacWindowToRootWindow( &x,&y ) ; + OffsetRgn( rgn , -x , -y ) ; wxMacWindowStateSaver sv( this ) ; SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ; MacDoRedraw( rgn , 0 ) ; @@ -587,7 +651,9 @@ void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control) void wxRemoveMacControlAssociation(wxWindow *control) { - wxWinMacControlList.DeleteObject(control); + // remove all associations pointing to us + while ( wxWinMacControlList.DeleteObject(control) ) + {} } #else @@ -614,13 +680,22 @@ void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control) void wxRemoveMacControlAssociation(wxWindow *control) { // iterate over all the elements in the class - MacControlMap::iterator it; - for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it ) + // is the iterator stable ? as we might have two associations pointing to the same wxWindow + // we should go on... + + bool found = true ; + while( found ) { - if ( it->second == control ) + found = false ; + MacControlMap::iterator it; + for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it ) { - wxWinMacControlList.erase(it); - break; + if ( it->second == control ) + { + wxWinMacControlList.erase(it); + found = true ; + break; + } } } } @@ -651,20 +726,22 @@ void wxWindowMac::Init() m_peer = NULL ; m_frozenness = 0 ; #if WXWIN_COMPATIBILITY_2_4 - m_backgroundTransparent = FALSE; + m_backgroundTransparent = false; #endif // as all windows are created with WS_VISIBLE style... - m_isShown = TRUE; + m_isShown = true; m_hScrollBar = NULL ; m_vScrollBar = NULL ; m_macBackgroundBrush = wxNullBrush ; - m_macIsUserPane = TRUE; + m_macIsUserPane = true; #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)); } @@ -674,7 +751,7 @@ wxWindowMac::~wxWindowMac() { SendDestroyEvent(); - m_isBeingDeleted = TRUE; + m_isBeingDeleted = true; MacInvalidateBorders() ; @@ -773,10 +850,10 @@ bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id, long style, const wxString& name) { - wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindowMac without parent") ); + wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") ); if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) - return FALSE; + return false; m_windowVariant = parent->GetWindowVariant() ; @@ -814,10 +891,10 @@ bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id, wxWindowCreateEvent event(this); GetEventHandler()->AddPendingEvent(event); - return TRUE; + return true; } -void wxWindowMac::MacChildAdded() +void wxWindowMac::MacChildAdded() { if ( m_vScrollBar ) { @@ -1032,17 +1109,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 @@ -1085,7 +1162,7 @@ bool wxWindowMac::MacGetBoundsForControl(const wxPoint& pos, int& w, int& h , bool adjustOrigin ) const { bool isCompositing = MacGetTopLevelWindow()->MacUsesCompositing() ; - + // the desired size, minus the border pixels gives the correct size of the control x = (int)pos.x; @@ -1134,6 +1211,10 @@ void wxWindowMac::DoGetPosition(int *x, int *y) const int x1 = bounds.left ; int y1 = bounds.top ; + // get the wx window position from the native one + x1 -= MacGetLeftBorderSize() ; + y1 -= MacGetTopBorderSize() ; + if ( !IsTopLevel() ) { wxWindow *parent = GetParent(); @@ -1254,9 +1335,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 ; @@ -1275,8 +1360,6 @@ void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom ) { - bool isCompositing = MacGetTopLevelWindow()->MacUsesCompositing() ; - RgnHandle rgn = NewRgn() ; if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) { @@ -1285,7 +1368,7 @@ void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , in GetRegionBounds( rgn , &content ) ; m_peer->GetRect( &structure ) ; OffsetRect( &structure, -structure.left , -structure.top ) ; - + left = content.left - structure.left ; top = content.top - structure.top ; right = structure.right - content.right ; @@ -1328,7 +1411,6 @@ wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const // Get size *available for subwindows* i.e. excluding menu bar etc. void wxWindowMac::DoGetClientSize(int *x, int *y) const { - bool isCompositing = MacGetTopLevelWindow()->MacUsesCompositing() ; int ww, hh; RgnHandle rgn = NewRgn() ; @@ -1348,11 +1430,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; @@ -1362,17 +1444,17 @@ void wxWindowMac::DoGetClientSize(int *x, int *y) const bool wxWindowMac::SetCursor(const wxCursor& cursor) { if (m_cursor == cursor) - return FALSE; + return false; if (wxNullCursor == cursor) { if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) ) - return FALSE ; + return false ; } else { if ( ! wxWindowBase::SetCursor( cursor ) ) - return FALSE ; + return false ; } wxASSERT_MSG( m_cursor.Ok(), @@ -1406,7 +1488,7 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) m_cursor.MacInstall() ; } - return TRUE ; + return true ; } #if wxUSE_MENUS @@ -1444,7 +1526,7 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) menu->SetInvokingWindow(NULL); - return TRUE; + return true; } #endif @@ -1464,7 +1546,7 @@ void wxWindowMac::DoSetToolTip(wxToolTip *tooltip) #endif // wxUSE_TOOLTIPS -void wxWindowMac::MacInvalidateBorders() +void wxWindowMac::MacInvalidateBorders() { if ( m_peer == NULL ) return ; @@ -1472,18 +1554,18 @@ void wxWindowMac::MacInvalidateBorders() bool vis = MacIsReallyShown() ; if ( !vis ) return ; - + int outerBorder = MacGetLeftBorderSize() ; if ( m_peer->NeedsFocusRect() && m_peer->HasFocus() ) outerBorder += 4 ; if ( outerBorder == 0 ) return ; - - // now we know that we have something to do at all + + // now we know that we have something to do at all // as the borders are drawn on the parent we have to properly invalidate all these areas - RgnHandle updateInner = NewRgn() , + RgnHandle updateInner = NewRgn() , updateOuter = NewRgn() ; // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon @@ -1625,7 +1707,7 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) if ((m_maxWidth != -1) && (actualWidth > m_maxWidth)) actualWidth = m_maxWidth; if ((m_maxHeight != -1) && (actualHeight > m_maxHeight)) - actualHeight = m_maxHeight; + actualHeight = m_maxHeight; bool doMove = false ; bool doResize = false ; @@ -1641,10 +1723,10 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) if ( doMove || doResize ) { - // as the borders are drawn outside the native control, we adjust now + // as the borders are drawn outside the native control, we adjust now - wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ), - wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) , + wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ), + wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) , actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ; Rect r ; @@ -1656,11 +1738,11 @@ 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() ; @@ -1702,12 +1784,12 @@ wxSize wxWindowMac::DoGetBestSize() const { bestsize.bottom = 16 ; } -#if wxUSE_SPINBTN +#if wxUSE_SPINBTN else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) ) { bestsize.bottom = 24 ; } -#endif // wxUSE_SPINBTN +#endif // wxUSE_SPINBTN else { // return wxWindowBase::DoGetBestSize() ; @@ -1796,11 +1878,16 @@ void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags) wxPoint wxWindowMac::GetClientAreaOrigin() const { - bool isCompositing = MacGetTopLevelWindow()->MacUsesCompositing() ; RgnHandle rgn = NewRgn() ; Rect content ; - m_peer->GetRegion( kControlContentMetaPart , rgn ) ; - GetRegionBounds( rgn , &content ) ; + if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) + { + GetRegionBounds( rgn , &content ) ; + } + else + { + content.left = content.top = 0 ; + } DisposeRgn( rgn ) ; return wxPoint( content.left + MacGetLeftBorderSize( ) , content.top + MacGetTopBorderSize( ) ); } @@ -1840,7 +1927,7 @@ bool wxWindowMac::Show(bool show) { bool former = MacIsReallyShown() ; if ( !wxWindowBase::Show(show) ) - return FALSE; + return false; // TODO use visibilityChanged Carbon Event for OSX if ( m_peer ) @@ -1849,7 +1936,7 @@ bool wxWindowMac::Show(bool show) } if ( former != MacIsReallyShown() ) MacPropagateVisibilityChanged() ; - return TRUE; + return true; } bool wxWindowMac::Enable(bool enable) @@ -1857,13 +1944,13 @@ bool wxWindowMac::Enable(bool enable) wxASSERT( m_peer->Ok() ) ; bool former = MacIsReallyEnabled() ; if ( !wxWindowBase::Enable(enable) ) - return FALSE; + return false; m_peer->Enable( enable ) ; if ( former != MacIsReallyEnabled() ) MacPropagateEnabledStateChanged() ; - return TRUE; + return true; } // @@ -1943,7 +2030,7 @@ 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(); @@ -2175,63 +2262,48 @@ void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin ) bool hasBothScrollbars = ( m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ; m_peer->GetRect( &rect ) ; - InsetRect( &rect, -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ; + // back to the surrounding frame rectangle + InsetRect( &rect, -1 , -1 ) ; #if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 if ( UMAGetSystemVersion() >= 0x1030 ) { - Rect srect = rect ; + CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left , + rect.bottom - rect.top ) ; + HIThemeFrameDrawInfo info ; memset( &info, 0 , sizeof( info ) ) ; - + info.version = 0 ; info.kind = 0 ; info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; info.isFocused = hasFocus ; - bool draw = false ; CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ; wxASSERT( cgContext ) ; - + if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) ) { - SInt32 border = 0 ; - GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ; - InsetRect( &srect , border , border ); info.kind = kHIThemeFrameTextFieldSquare ; - draw = true ; + HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; } else if (HasFlag(wxSIMPLE_BORDER)) { - SInt32 border = 0 ; - GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; - InsetRect( &srect , border , border ); info.kind = kHIThemeFrameListBox ; - draw = true ; - } - - if ( draw ) - { - CGRect cgrect = CGRectMake( srect.left , srect.top , srect.right - srect.left , - srect.bottom - srect.top ) ; HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; } else if ( hasFocus ) { - srect = rect ; - CGRect cgrect = CGRectMake( srect.left , srect.top , srect.right - srect.left , - srect.bottom - srect.top ) ; HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ; } - + m_peer->GetRect( &rect ) ; if ( hasBothScrollbars ) { - srect = rect ; int size = m_hScrollBar->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL ? 16 : 12 ; - CGRect cgrect = CGRectMake( srect.right - size , srect.bottom - size , size , size ) ; - CGPoint cgpoint = CGPointMake( srect.right - size , srect.bottom - size ) ; - HIThemeGrowBoxDrawInfo info ; + CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ; + CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ; + HIThemeGrowBoxDrawInfo info ; memset( &info, 0 , sizeof( info ) ) ; info.version = 0 ; info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; @@ -2254,29 +2326,21 @@ void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin ) if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) ) { - Rect srect = rect ; - SInt32 border = 0 ; - GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ; - InsetRect( &srect , border , border ); - DrawThemeEditTextFrame(&srect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ; + DrawThemeEditTextFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ; } else if (HasFlag(wxSIMPLE_BORDER)) { - Rect srect = rect ; - SInt32 border = 0 ; - GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; - InsetRect( &srect , border , border ); DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ; } - + if ( hasFocus ) { - Rect srect = rect ; - DrawThemeFocusRect( &srect , true ) ; + DrawThemeFocusRect( &rect , true ) ; } + if ( hasBothScrollbars ) { - // GetThemeStandaloneGrowBoxBounds + // GetThemeStandaloneGrowBoxBounds //DrawThemeStandaloneNoGrowBox } } @@ -2339,12 +2403,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 @@ -2362,16 +2425,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; @@ -2383,9 +2469,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 ; @@ -2398,7 +2484,7 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) ScrollRect( &scrollrect , dx , dy , updateRgn ) ; // now scroll the former update region as well and add the new update region - + WindowRef rootWindow = (WindowRef) MacGetTopLevelWindowRef() ; RgnHandle formerUpdateRgn = NewRgn() ; RgnHandle scrollRgn = NewRgn() ; @@ -2419,7 +2505,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()) @@ -2503,7 +2589,8 @@ void wxWindowMac::OnSetFocus(wxFocusEvent& event) wxMacWindowStateSaver sv( this ) ; Rect rect ; m_peer->GetRect( &rect ) ; - InsetRect( &rect, -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ; + // auf den umgebenden Rahmen zurĀŸck + InsetRect( &rect, -1 , -1 ) ; wxTopLevelWindowMac* top = MacGetTopLevelWindow(); if (top ) @@ -2602,10 +2689,12 @@ bool wxWindowMac::MacSetupCursor( const wxPoint& pt) wxString wxWindowMac::MacGetToolTipString( wxPoint &pt ) { +#if wxUSE_TOOLTIPS if ( m_tooltip ) { return m_tooltip->GetTip() ; } +#endif return wxEmptyString ; } @@ -2618,39 +2707,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 @@ -2666,82 +2723,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() */ ) - { - m_peer->GetRect( &r ) ; - r.left -= MacGetLeftBorderSize() ; - r.top -= MacGetTopBorderSize() ; - r.bottom += MacGetBottomBorderSize() ; - r.right += MacGetRightBorderSize() ; + Rect rIncludingOuterStructures ; - r.right -= r.left ; - r.bottom -= r.top ; - r.left = 0 ; - r.top = 0 ; + m_peer->GetRect( &r ) ; + r.left -= MacGetLeftBorderSize() ; + r.top -= MacGetTopBorderSize() ; + r.bottom += MacGetBottomBorderSize() ; + r.right += MacGetRightBorderSize() ; - if ( includeOuterStructures ) - InsetRect( &r , -4 , -4 ) ; - RectRgn( visRgn , &r ) ; + r.right -= r.left ; + r.bottom -= r.top ; + r.left = 0 ; + r.top = 0 ; + + rIncludingOuterStructures = r ; + InsetRect( &rIncludingOuterStructures , -4 , -4 ) ; - if ( !IsTopLevel() ) + 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 ) + { + int x , y ; + wxSize size ; + + if ( parent->MacIsChildOfClientArea(child) ) { - 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 ) ; + 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 || ( - 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()) ; + parent->MacWindowToRootWindow( &x, &y ) ; + MacRootWindowToWindow( &x , &y ) ; - SectRgn( visRgn , tempRgn , visRgn ) ; - } - if ( parent->IsTopLevel() ) - break ; - child = parent ; - parent = child->GetParent() ; - } + Rect rparent = { y , x , y + size.y , x + size.x } ; + + // the wxwindow and client rects will always be clipped + SectRect( &r , &rparent , &r ) ; + SectRect( &rClient , &rparent , &rClient ) ; + + // 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 ; } /* @@ -2756,7 +2858,7 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) // wxLogDebug(wxT("update for %s bounds %d , %d , %d , %d"),wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left , updatebounds.top , updatebounds.right , updatebounds.bottom ) ; - if ( !EmptyRgn(updatergn) ) + if ( !EmptyRgn(updatergn) ) { RgnHandle newupdate = NewRgn() ; wxSize point = GetClientSize() ; @@ -2770,12 +2872,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 ); @@ -2909,6 +3011,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 ) @@ -2927,10 +3037,10 @@ void wxWindowMac::MacRepositionScrollBars() width -= MacGetLeftBorderSize() + MacGetRightBorderSize(); height -= MacGetTopBorderSize() + MacGetBottomBorderSize(); - wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ; - wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ; - wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ; - wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ; + wxPoint vPoint(width-scrlsize, 0) ; + wxSize vSize(scrlsize, height - adjust) ; + wxPoint hPoint(0 , height-scrlsize ) ; + wxSize hSize( width - adjust, scrlsize) ; /* int x = 0 ; int y = 0 ; @@ -2995,6 +3105,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(); @@ -3024,21 +3135,19 @@ long wxWindowMac::MacGetLeftBorderSize( ) const if( IsTopLevel() ) return 0 ; - if (m_windowStyle & wxRAISED_BORDER || m_windowStyle & wxSUNKEN_BORDER ) - { - SInt32 border = 3 ; - return border ; - } - else if ( m_windowStyle &wxDOUBLE_BORDER) + SInt32 border = 0 ; + + if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) ) { - SInt32 border = 3 ; - return border ; + GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ; + border += 1 ; // the metric above is only the 'outset' outside the simple frame rect } - else if (m_windowStyle &wxSIMPLE_BORDER) + else if (HasFlag(wxSIMPLE_BORDER)) { - return 1 ; + GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; + border += 1 ; // the metric above is only the 'outset' outside the simple frame rect } - return 0 ; + return border ; } long wxWindowMac::MacGetRightBorderSize( ) const