X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6548fabe00fca91c3638eaab45dd4132286ed18e..37de49a3225b9e87ec950f73d361335c73ad3f7f:/src/mac/carbon/window.cpp diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index 0d5bf2fab7..9088d2f57a 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -35,6 +35,7 @@ #include "wx/spinctrl.h" #include "wx/log.h" #include "wx/geometry.h" +#include "wx/textctrl.h" #include "wx/toolbar.h" #include "wx/dc.h" @@ -51,6 +52,8 @@ #ifndef __DARWIN__ #include #include +#include +#include #endif #if TARGET_API_MAC_OSX @@ -120,7 +123,12 @@ static const EventTypeSpec eventList[] = { kEventClassControl , kEventControlEnabledStateChanged } , { kEventClassControl , kEventControlHiliteChanged } , { kEventClassControl , kEventControlSetFocusPart } , -// { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only + + { kEventClassService , kEventServiceGetTypes }, + { kEventClassService , kEventServiceCopy }, + { kEventClassService , kEventServicePaste }, + + // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only // { kEventClassControl , kEventControlBoundsChanged } , #endif } ; @@ -222,6 +230,8 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl event.SetEventObject(thisWindow); thisWindow->GetEventHandler()->ProcessEvent(event) ; } + if ( thisWindow->MacIsUserPane() ) + result = noErr ; } break ; #endif @@ -236,6 +246,84 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl return result ; } +static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +{ + OSStatus result = eventNotHandledErr ; + + wxMacCarbonEvent cEvent( event ) ; + + ControlRef controlRef ; + wxWindowMac* thisWindow = (wxWindowMac*) data ; + wxTextCtrl* textCtrl = wxDynamicCast( thisWindow , wxTextCtrl ) ; + cEvent.GetParameter( kEventParamDirectObject , &controlRef ) ; + + switch( GetEventKind( event ) ) + { + case kEventServiceGetTypes : + if( textCtrl ) + { + long from, to ; + textCtrl->GetSelection( &from , &to ) ; + + CFMutableArrayRef copyTypes = 0 , pasteTypes = 0; + if( from != to ) + copyTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServiceCopyTypes , typeCFMutableArrayRef ) ; + if ( textCtrl->IsEditable() ) + pasteTypes = cEvent.GetParameter< CFMutableArrayRef >( kEventParamServicePasteTypes , typeCFMutableArrayRef ) ; + + static const OSType textDataTypes[] = { kTXNTextData /* , 'utxt' , 'PICT', 'MooV', 'AIFF' */ }; + for ( size_t i = 0 ; i < WXSIZEOF(textDataTypes) ; ++i ) + { + CFStringRef typestring = CreateTypeStringWithOSType(textDataTypes[i]); + if ( typestring ) + { + if ( copyTypes ) + CFArrayAppendValue (copyTypes, typestring) ; + if ( pasteTypes ) + CFArrayAppendValue (pasteTypes, typestring) ; + CFRelease( typestring ) ; + } + } + result = noErr ; + } + break ; + case kEventServiceCopy : + if ( textCtrl ) + { + long from, to ; + textCtrl->GetSelection( &from , &to ) ; + wxString val = textCtrl->GetValue() ; + val = val.Mid( from , to - from ) ; + ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ; + verify_noerr( ClearScrap( &scrapRef ) ) ; + verify_noerr( PutScrapFlavor( scrapRef , kTXNTextData , 0 , val.Length() , val.c_str() ) ) ; + result = noErr ; + } + break ; + case kEventServicePaste : + if ( textCtrl ) + { + ScrapRef scrapRef = cEvent.GetParameter< ScrapRef > ( kEventParamScrapRef , typeScrapRef ) ; + Size textSize, pastedSize ; + verify_noerr( GetScrapFlavorSize (scrapRef, kTXNTextData, &textSize) ) ; + textSize++ ; + char *content = new char[textSize] ; + GetScrapFlavorData (scrapRef, kTXNTextData, &pastedSize, content ); + content[textSize-1] = 0 ; +#if wxUSE_UNICODE + textCtrl->WriteText( wxString( content , wxConvLocal ) ); +#else + textCtrl->WriteText( wxString( content ) ) ; +#endif + delete[] content ; + result = noErr ; + } + break ; + } + + return result ; +} + pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { OSStatus result = eventNotHandledErr ; @@ -245,6 +333,8 @@ pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef case kEventClassControl : result = wxMacWindowControlEventHandler( handler, event, data ) ; break ; + case kEventClassService : + result = wxMacWindowServiceEventHandler( handler, event , data ) ; default : break ; } @@ -469,8 +559,25 @@ pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode p // constructors and such // ---------------------------------------------------------------------------- +wxWindowMac::wxWindowMac() +{ + Init(); +} + +wxWindowMac::wxWindowMac(wxWindowMac *parent, + wxWindowID id, + const wxPoint& pos , + const wxSize& size , + long style , + const wxString& name ) +{ + Init(); + Create(parent, id, pos, size, style, name); +} + void wxWindowMac::Init() { + m_peer = NULL ; m_frozenness = 0 ; #if WXWIN_COMPATIBILITY_2_4 m_backgroundTransparent = FALSE; @@ -483,8 +590,6 @@ void wxWindowMac::Init() m_vScrollBar = NULL ; m_macBackgroundBrush = wxNullBrush ; - m_macControl = NULL ; - m_macIsUserPane = TRUE; // make sure all proc ptrs are available @@ -546,13 +651,12 @@ wxWindowMac::~wxWindowMac() if (parent->GetDefaultItem() == (wxButton*) this) parent->SetDefaultItem(NULL); } - if ( (ControlRef) m_macControl ) + if ( m_peer && m_peer->Ok() ) { // in case the callback might be called during destruction wxRemoveMacControlAssociation( this) ; - ::SetControlColorProc( (ControlRef) m_macControl , NULL ) ; - ::DisposeControl( (ControlRef) m_macControl ) ; - m_macControl = NULL ; + ::SetControlColorProc( *m_peer , NULL ) ; + ::DisposeControl( *m_peer ) ; } if ( g_MacLastWindow == this ) @@ -577,14 +681,19 @@ wxWindowMac::~wxWindowMac() m_dropTarget = NULL; } #endif // wxUSE_DRAG_AND_DROP + delete m_peer ; +} + +WXWidget wxWindowMac::GetHandle() const +{ + return (WXWidget) (ControlRef) *m_peer ; } -// void wxWindowMac::MacInstallEventHandler() { - wxAssociateControlWithMacControl( (ControlRef) m_macControl , this ) ; - InstallControlEventHandler( (ControlRef) m_macControl, GetwxMacWindowEventHandlerUPP(), + wxAssociateControlWithMacControl( *m_peer , this ) ; + InstallControlEventHandler( *m_peer, GetwxMacWindowEventHandlerUPP(), GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_macControlEventHandler); @@ -610,28 +719,38 @@ bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id, { Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ; - UInt32 features = kControlSupportsEmbedding | kControlSupportsLiveFeedback | kControlHasSpecialBackground | - kControlSupportsCalcBestRect | kControlHandlesTracking | kControlSupportsFocus | kControlWantsActivate | kControlWantsIdle; - - ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, kControlSupportsEmbedding , (ControlRef*) &m_macControl); + UInt32 features = 0 + | kControlSupportsEmbedding +// | kControlSupportsLiveFeedback +// | kControlHasSpecialBackground +// | kControlSupportsCalcBestRect +// | kControlHandlesTracking + | kControlSupportsFocus +// | kControlWantsActivate +// | kControlWantsIdle + ; + + m_peer = new wxMacControl() ; + ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , *m_peer); + MacPostControlCreate(pos,size) ; #if !TARGET_API_MAC_OSX - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneDrawProcTag, + SetControlData(*m_peer,kControlEntireControl,kControlUserPaneDrawProcTag, sizeof(gControlUserPaneDrawUPP),(Ptr) &gControlUserPaneDrawUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneHitTestProcTag, + SetControlData(*m_peer,kControlEntireControl,kControlUserPaneHitTestProcTag, sizeof(gControlUserPaneHitTestUPP),(Ptr) &gControlUserPaneHitTestUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneTrackingProcTag, + SetControlData(*m_peer,kControlEntireControl,kControlUserPaneTrackingProcTag, sizeof(gControlUserPaneTrackingUPP),(Ptr) &gControlUserPaneTrackingUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneIdleProcTag, + SetControlData(*m_peer,kControlEntireControl,kControlUserPaneIdleProcTag, sizeof(gControlUserPaneIdleUPP),(Ptr) &gControlUserPaneIdleUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneKeyDownProcTag, + SetControlData(*m_peer,kControlEntireControl,kControlUserPaneKeyDownProcTag, sizeof(gControlUserPaneKeyDownUPP),(Ptr) &gControlUserPaneKeyDownUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneActivateProcTag, + SetControlData(*m_peer,kControlEntireControl,kControlUserPaneActivateProcTag, sizeof(gControlUserPaneActivateUPP),(Ptr) &gControlUserPaneActivateUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneFocusProcTag, + SetControlData(*m_peer,kControlEntireControl,kControlUserPaneFocusProcTag, sizeof(gControlUserPaneFocusUPP),(Ptr) &gControlUserPaneFocusUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneBackgroundProcTag, + SetControlData(*m_peer,kControlEntireControl,kControlUserPaneBackgroundProcTag, sizeof(gControlUserPaneBackgroundUPP),(Ptr) &gControlUserPaneBackgroundUPP); #endif } @@ -652,15 +771,15 @@ bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id, void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size) { - wxASSERT_MSG( (ControlRef) m_macControl != NULL , wxT("No valid mac control") ) ; + wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ; - ::SetControlReference( (ControlRef) m_macControl , (long) this ) ; + ::SetControlReference( *m_peer , (long) this ) ; MacInstallEventHandler(); ControlRef container = (ControlRef) GetParent()->GetHandle() ; wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; - ::EmbedControl( (ControlRef) m_macControl , container ) ; + ::EmbedControl( *m_peer , container ) ; // adjust font, controlsize etc DoSetWindowVariant( m_windowVariant ) ; @@ -668,38 +787,28 @@ void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size) #if !TARGET_API_MAC_OSX // eventually we can fix some clipping issues be reactivating this hook //if ( m_macIsUserPane ) - // SetControlColorProc( (ControlRef) m_macControl , wxMacSetupControlBackgroundUPP ) ; + // SetControlColorProc( *m_peer , wxMacSetupControlBackgroundUPP ) ; #endif - UMASetControlTitle( (ControlRef) m_macControl , wxStripMenuCodes(m_label) , m_font.GetEncoding() ) ; + UMASetControlTitle( *m_peer , wxStripMenuCodes(m_label) , m_font.GetEncoding() ) ; - wxSize new_size = size ; if (!m_macIsUserPane) - { - wxSize best_size( DoGetBestSize() ); - - if (size.x == -1) { - new_size.x = best_size.x; - } - if (size.y == -1) { - new_size.y = best_size.y; - } - SetSize( pos.x, pos.y , new_size.x, new_size.y,wxSIZE_USE_EXISTING ); + { + SetInitialBestSize(size); } SetCursor( *wxSTANDARD_CURSOR ) ; - } void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) { // Don't assert, in case we set the window variant before // the window is created - // wxASSERT( m_macControl != NULL ) ; + // wxASSERT( m_peer->Ok() ) ; m_windowVariant = variant ; - if (!m_macControl) + if (m_peer == NULL || !m_peer->Ok()) return; ControlSize size ; @@ -740,7 +849,7 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) wxFAIL_MSG(_T("unexpected window variant")); break ; } - ::SetControlData( (ControlRef) m_macControl , kControlEntireControl, kControlSizeTag, sizeof( ControlSize ), &size ); + ::SetControlData( *m_peer , kControlEntireControl, kControlSizeTag, sizeof( ControlSize ), &size ); wxFont font ; font.MacCreateThemeFont( themeFont ) ; @@ -780,7 +889,7 @@ void wxWindowMac::MacUpdateControlFont() fontStyle.foreColor = MAC_WXCOLORREF(GetForegroundColour().GetPixel() ) ; fontStyle.flags |= kControlUseForeColorMask ; - ::SetControlFontStyle( (ControlRef) m_macControl , &fontStyle ); + ::SetControlFontStyle( *m_peer , &fontStyle ); Refresh() ; } @@ -831,14 +940,13 @@ bool wxWindowMac::SetBackgroundColour(const wxColour& col ) bool wxWindowMac::MacCanFocus() const { -#if 0 - // there is currently no way to determinate whether the window is running in full keyboard - // access mode, therefore we cannot rely on these features yet + // there is currently no way to determine whether the window is running in full keyboard + // access mode, therefore we cannot rely on these features, yet the only other way would be + // to issue a SetKeyboardFocus event and verify after whether it succeeded, this would risk problems + // in event handlers... UInt32 features = 0 ; - GetControlFeatures( (ControlRef) m_macControl , &features ) ; + GetControlFeatures( *m_peer , &features ) ; return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ; -#endif - return true ; } @@ -930,7 +1038,7 @@ void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y, int& w, int& h) const { Rect bounds ; - GetControlBounds( (ControlRef) m_macControl , &bounds ) ; + GetControlBounds( *m_peer , &bounds ) ; x = bounds.left ; @@ -942,11 +1050,7 @@ void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y, if ( tlw ) { Point tlworigin = { 0 , 0 } ; - GrafPtr port ; - bool swapped = QDSwapPort( UMAGetWindowPort( (WindowRef) tlw->MacGetWindowRef() ) , &port ) ; - ::LocalToGlobal( &tlworigin ) ; - if ( swapped ) - ::SetPort( port ) ; + QDLocalToGlobalPoint( UMAGetWindowPort( (WindowRef) tlw->MacGetWindowRef() ) , &tlworigin ) ; x = tlworigin.h ; y = tlworigin.v ; } @@ -981,7 +1085,7 @@ void wxWindowMac::DoGetSize(int *x, int *y) const #else Rect bounds ; - GetControlBounds( (ControlRef) m_macControl , &bounds ) ; + GetControlBounds( *m_peer , &bounds ) ; if(x) *x = bounds.right - bounds.left ; if(y) *y = bounds.bottom - bounds.top ; #endif @@ -1006,7 +1110,7 @@ void wxWindowMac::DoGetPosition(int *x, int *y) const if(y) *y = y1 ; #else Rect bounds ; - GetControlBounds( (ControlRef) m_macControl , &bounds ) ; + GetControlBounds( *m_peer , &bounds ) ; wxCHECK_RET( GetParent() , wxT("Missing Parent") ) ; int xx = bounds.left ; @@ -1041,8 +1145,7 @@ void wxWindowMac::DoScreenToClient(int *x, int *y) const if(x) localwhere.h = * x ; if(y) localwhere.v = * y ; - wxMacPortSaver s((GrafPtr)GetWindowPort( window )) ; - ::GlobalToLocal( &localwhere ) ; + QDGlobalToLocalPoint( GetWindowPort( window ) , &localwhere ) ; if(x) *x = localwhere.h ; if(y) *y = localwhere.v ; @@ -1069,9 +1172,7 @@ void wxWindowMac::DoClientToScreen(int *x, int *y) const Point localwhere = { 0,0 }; if(x) localwhere.h = * x ; if(y) localwhere.v = * y ; - - wxMacPortSaver s((GrafPtr)GetWindowPort( window )) ; - ::LocalToGlobal( &localwhere ) ; + QDLocalToGlobalPoint( GetWindowPort( window ) , &localwhere ) ; if(x) *x = localwhere.h ; if(y) *y = localwhere.v ; } @@ -1103,7 +1204,11 @@ void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const if ( y ) pt.y = *y ; if ( !IsTopLevel() ) - HIViewConvertPoint( &pt , (ControlRef) m_macControl , (ControlRef) MacGetTopLevelWindow()->GetHandle() ) ; + { + wxTopLevelWindowMac* top = MacGetTopLevelWindow(); + if (top) + HIViewConvertPoint( &pt , *m_peer , (ControlRef) top->GetHandle() ) ; + } if ( x ) *x = (int) pt.x ; if ( y ) *y = (int) pt.y ; @@ -1111,7 +1216,7 @@ void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const if ( !IsTopLevel() ) { Rect bounds ; - GetControlBounds( (ControlRef) m_macControl , &bounds ) ; + GetControlBounds( *m_peer , &bounds ) ; if(x) *x += bounds.left ; if(y) *y += bounds.top ; } @@ -1136,7 +1241,7 @@ void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const if ( y ) pt.y = *y ; if ( !IsTopLevel() ) - HIViewConvertPoint( &pt , (ControlRef) MacGetTopLevelWindow()->GetHandle() , (ControlRef) m_macControl ) ; + HIViewConvertPoint( &pt , (ControlRef) MacGetTopLevelWindow()->GetHandle() , *m_peer ) ; if ( x ) *x = (int) pt.x ; if ( y ) *y = (int) pt.y ; @@ -1144,7 +1249,7 @@ void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const if ( !IsTopLevel() ) { Rect bounds ; - GetControlBounds( (ControlRef) m_macControl , &bounds ) ; + GetControlBounds( *m_peer , &bounds ) ; if(x) *x -= bounds.left ; if(y) *y -= bounds.top ; } @@ -1165,17 +1270,17 @@ void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , in { RgnHandle rgn = NewRgn() ; Rect content ; - if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr ) + if ( GetControlRegion( *m_peer , kControlContentMetaPart , rgn ) == noErr ) { GetRegionBounds( rgn , &content ) ; DisposeRgn( rgn ) ; } else { - GetControlBounds( (ControlRef) m_macControl , &content ) ; + GetControlBounds( *m_peer , &content ) ; } Rect structure ; - GetControlBounds( (ControlRef) m_macControl , &structure ) ; + GetControlBounds( *m_peer , &structure ) ; #if !TARGET_API_MAC_OSX OffsetRect( &content , -structure.left , -structure.top ) ; #endif @@ -1193,17 +1298,17 @@ wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const Rect content ; - if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr ) + if ( GetControlRegion( *m_peer , kControlContentMetaPart , rgn ) == noErr ) { GetRegionBounds( rgn , &content ) ; DisposeRgn( rgn ) ; } else { - GetControlBounds( (ControlRef) m_macControl , &content ) ; + GetControlBounds( *m_peer , &content ) ; } Rect structure ; - GetControlBounds( (ControlRef) m_macControl , &structure ) ; + GetControlBounds( *m_peer , &structure ) ; #if !TARGET_API_MAC_OSX OffsetRect( &content , -structure.left , -structure.top ) ; #endif @@ -1225,18 +1330,18 @@ void wxWindowMac::DoGetClientSize(int *x, int *y) const RgnHandle rgn = NewRgn() ; Rect content ; - if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr ) + if ( GetControlRegion( *m_peer , kControlContentMetaPart , rgn ) == noErr ) { GetRegionBounds( rgn , &content ) ; DisposeRgn( rgn ) ; } else { - GetControlBounds( (ControlRef) m_macControl , &content ) ; + GetControlBounds( *m_peer , &content ) ; } #if !TARGET_API_MAC_OSX Rect structure ; - GetControlBounds( (ControlRef) m_macControl , &structure ) ; + GetControlBounds( *m_peer , &structure ) ; OffsetRect( &content , -structure.left , -structure.top ) ; #endif ww = content.right - content.left ; @@ -1343,7 +1448,16 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) { menu->SetInvokingWindow(this); menu->UpdateUI(); - ClientToScreen( &x , &y ) ; + + if ( x == -1 && y == -1 ) + { + wxPoint mouse = wxGetMousePosition(); + x = mouse.x; y = mouse.y; + } + else + { + ClientToScreen( &x , &y ) ; + } menu->MacBeforeDisplay( true ) ; long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ; @@ -1424,21 +1538,21 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) { // we don't adjust twice for the origin Rect r = wxMacGetBoundsForControl(this , wxPoint( actualX,actualY), wxSize( actualWidth, actualHeight ) , false ) ; - bool vis = IsControlVisible( (ControlRef) m_macControl ) ; + bool vis = IsControlVisible( *m_peer ) ; #if TARGET_API_MAC_OSX // the HIViewSetFrame call itself should invalidate the areas, but when testing with the UnicodeTextCtrl it does not ! if ( vis ) - SetControlVisibility( (ControlRef)m_macControl , false , true ) ; + SetControlVisibility( *m_peer , false , true ) ; HIRect hir = { r.left , r.top , r.right - r.left , r.bottom - r.top } ; - HIViewSetFrame ( (ControlRef) m_macControl , &hir ) ; + HIViewSetFrame ( *m_peer , &hir ) ; if ( vis ) - SetControlVisibility( (ControlRef)m_macControl , true , true ) ; + SetControlVisibility( *m_peer , true , true ) ; #else if ( vis ) - SetControlVisibility( (ControlRef)m_macControl , false , true ) ; - SetControlBounds( (ControlRef) m_macControl , &r ) ; + SetControlVisibility( *m_peer , false , true ) ; + SetControlBounds( *m_peer , &r ) ; if ( vis ) - SetControlVisibility( (ControlRef)m_macControl , true , true ) ; + SetControlVisibility( *m_peer , true , true ) ; #endif MacRepositionScrollBars() ; if ( doMove ) @@ -1468,7 +1582,7 @@ wxSize wxWindowMac::DoGetBestSize() const Rect bestsize = { 0 , 0 , 0 , 0 } ; short baselineoffset ; int bestWidth, bestHeight ; - ::GetBestControlRect( (ControlRef) m_macControl , &bestsize , &baselineoffset ) ; + ::GetBestControlRect( *m_peer , &bestsize , &baselineoffset ) ; if ( EmptyRect( &bestsize ) ) { @@ -1575,13 +1689,18 @@ wxPoint wxWindowMac::GetClientAreaOrigin() const { RgnHandle rgn = NewRgn() ; Rect content ; - GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) ; + GetControlRegion( *m_peer , kControlContentMetaPart , rgn ) ; GetRegionBounds( rgn , &content ) ; DisposeRgn( rgn ) ; #if !TARGET_API_MAC_OSX - Rect structure ; - GetControlBounds( (ControlRef) m_macControl , &structure ) ; - OffsetRect( &content , -structure.left , -structure.top ) ; + // if the content rgn is empty / not supported + // don't attempt to correct the coordinates to wxWindow relative ones + if (!::EmptyRect( &content ) ) + { + Rect structure ; + GetControlBounds( *m_peer , &structure ) ; + OffsetRect( &content , -structure.left , -structure.top ) ; + } #endif return wxPoint( content.left + MacGetLeftBorderSize( ) , content.top + MacGetTopBorderSize( ) ); @@ -1606,9 +1725,9 @@ void wxWindowMac::SetTitle(const wxString& title) { m_label = wxStripMenuCodes(title) ; - if ( m_macControl ) + if ( m_peer && m_peer->Ok() ) { - UMASetControlTitle( (ControlRef) m_macControl , m_label , m_font.GetEncoding() ) ; + UMASetControlTitle( *m_peer , m_label , m_font.GetEncoding() ) ; } Refresh() ; } @@ -1626,7 +1745,7 @@ bool wxWindowMac::Show(bool show) // TODO use visibilityChanged Carbon Event for OSX bool former = MacIsReallyShown() ; - SetControlVisibility( (ControlRef) m_macControl , show , true ) ; + SetControlVisibility( *m_peer , show , true ) ; if ( former != MacIsReallyShown() ) MacPropagateVisibilityChanged() ; return TRUE; @@ -1634,15 +1753,22 @@ bool wxWindowMac::Show(bool show) bool wxWindowMac::Enable(bool enable) { - wxASSERT( m_macControl != NULL ) ; + wxASSERT( m_peer->Ok() ) ; if ( !wxWindowBase::Enable(enable) ) return FALSE; bool former = MacIsReallyEnabled() ; +#if TARGET_API_MAC_OSX + if ( enable ) + EnableControl( *m_peer ) ; + else + DisableControl( *m_peer ) ; +#else if ( enable ) - EnableControl( (ControlRef) m_macControl ) ; + ActivateControl( *m_peer ) ; else - DisableControl( (ControlRef) m_macControl ) ; + DeactivateControl( *m_peer ) ; +#endif if ( former != MacIsReallyEnabled() ) MacPropagateEnabledStateChanged() ; @@ -1725,7 +1851,7 @@ bool wxWindowMac::MacIsReallyShown() { // only under OSX the visibility of the TLW is taken into account #if TARGET_API_MAC_OSX - return IsControlVisible( (ControlRef) m_macControl ) ; + return IsControlVisible( *m_peer ) ; #else wxWindow* win = this ; while( win->IsShown() ) @@ -1744,12 +1870,23 @@ bool wxWindowMac::MacIsReallyShown() bool wxWindowMac::MacIsReallyEnabled() { - return IsControlEnabled( (ControlRef) m_macControl ) ; +#if TARGET_API_MAC_OSX + return IsControlEnabled( *m_peer ) ; +#else + return IsControlActive( *m_peer ) ; +#endif } bool wxWindowMac::MacIsReallyHilited() { - return IsControlActive( (ControlRef) m_macControl ) ; + return IsControlActive( *m_peer ) ; +} + +void wxWindowMac::MacFlashInvalidAreas() +{ +#if TARGET_API_MAC_OSX + HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ; +#endif } // @@ -1797,7 +1934,7 @@ void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect) { #if TARGET_API_MAC_OSX if ( rect == NULL ) - HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ; + HIViewSetNeedsDisplay( *m_peer , true ) ; else { RgnHandle update = NewRgn() ; @@ -1805,7 +1942,7 @@ void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect) SectRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , update , update ) ; wxPoint origin = GetClientAreaOrigin() ; OffsetRgn( update, origin.x , origin.y ) ; - HIViewSetNeedsDisplayInRegion( (ControlRef) m_macControl , update , true ) ; + HIViewSetNeedsDisplayInRegion( *m_peer , update , true ) ; } #else /* @@ -1822,16 +1959,16 @@ void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect) InvalWindowRgn( (WindowRef) MacGetTopLevelWindowRef() , updateRgn ) ; DisposeRgn(updateRgn) ; */ - if ( IsControlVisible( (ControlRef) m_macControl ) ) + if ( IsControlVisible( *m_peer ) ) { - SetControlVisibility( (ControlRef) m_macControl , false , false ) ; - SetControlVisibility( (ControlRef) m_macControl , true , true ) ; + SetControlVisibility( *m_peer , false , false ) ; + SetControlVisibility( *m_peer , true , true ) ; } /* if ( MacGetTopLevelWindow() == NULL ) return ; - if ( !IsControlVisible( (ControlRef) m_macControl ) ) + if ( !IsControlVisible( *m_peer ) ) return ; wxPoint client = GetClientAreaOrigin(); @@ -1875,7 +2012,7 @@ void wxWindowMac::Freeze() #if TARGET_API_MAC_OSX if ( !m_frozenness++ ) { - HIViewSetDrawingEnabled( (HIViewRef) m_macControl , false ) ; + HIViewSetDrawingEnabled( *m_peer , false ) ; } #endif } @@ -1908,9 +2045,9 @@ void wxWindowMac::Thaw() if ( !--m_frozenness ) { - HIViewSetDrawingEnabled( (HIViewRef) m_macControl , true ) ; - InvalidateControlAndChildren( (HIViewRef) m_macControl ) ; - // HIViewSetNeedsDisplay( (HIViewRef) m_macControl , true ) ; + HIViewSetDrawingEnabled( *m_peer , true ) ; + InvalidateControlAndChildren( *m_peer ) ; + // HIViewSetNeedsDisplay( *m_peer , true ) ; } #endif } @@ -1918,7 +2055,7 @@ void wxWindowMac::Thaw() void wxWindowMac::MacRedrawControl() { /* - if ( (ControlRef) m_macControl && MacGetTopLevelWindowRef() && IsControlVisible( (ControlRef) m_macControl ) ) + if ( *m_peer && MacGetTopLevelWindowRef() && IsControlVisible( *m_peer ) ) { #if TARGET_API_MAC_CARBON Update() ; @@ -1927,7 +2064,7 @@ void wxWindowMac::MacRedrawControl() wxMacPortSetter helper(&dc) ; wxMacWindowClipper clipper(this) ; wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ; - UMADrawControl( (ControlRef) m_macControl ) ; + UMADrawControl( *m_peer ) ; #endif } */ @@ -2170,57 +2307,62 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) { - wxClientDC dc(this) ; - wxMacPortSetter helper(&dc) ; int width , height ; GetClientSize( &width , &height ) ; - +#if TARGET_API_MAC_OSX + // 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 + HIRect scrollrect = CGRectMake( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ; + if ( rect ) + { + HIRect scrollarea = CGRectMake( rect->x , rect->y , rect->width , rect->height) ; + scrollrect = CGRectIntersection( scrollrect , scrollarea ) ; + } + if ( HIViewGetNeedsDisplay( *m_peer ) ) + { + // becuase HIViewScrollRect does not scroll the already invalidated area we have two options + // either immediate redraw or full invalidate +#if 1 + // is the better overall solution, as it does not slow down scrolling + HIViewSetNeedsDisplay( *m_peer , true ) ; +#else + // this would be the preferred version for fast drawing controls + if( UMAGetSystemVersion() < 0x1030 ) + Update() ; + else + HIViewRender(*m_peer) ; +#endif + } + HIViewScrollRect ( *m_peer , &scrollrect , dx ,dy ) ; +#else wxPoint pos; pos.x = pos.y = 0; - + Rect scrollrect; - // TODO take out the boundaries - GetControlBounds( (ControlRef) m_macControl, &scrollrect); - RgnHandle updateRgn = NewRgn() ; - if ( rect ) - { - Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) , - dc.XLOG2DEVMAC(rect->x + rect->width) } ; - SectRect( &scrollrect , &r , &scrollrect ) ; - } - ScrollRect( &scrollrect , dx , dy , updateRgn ) ; -#if TARGET_CARBON - //KO: The docs say ScrollRect creates an update region, which thus calls an update event - // but it seems the update only refreshes the background of the control, rather than calling - // kEventControlDraw, so we need to force a proper update here. There has to be a better - // way of doing this... (Note that code below under !TARGET_CARBON does not work either...) - Update(); -#endif - // we also have to scroll the update rgn in this rectangle - // in order not to loose updates -#if !TARGET_CARBON - WindowRef rootWindow = (WindowRef) MacGetTopLevelWindowRef() ; - RgnHandle formerUpdateRgn = NewRgn() ; - RgnHandle scrollRgn = NewRgn() ; - RectRgn( scrollRgn , &scrollrect ) ; - GetWindowUpdateRgn( rootWindow , formerUpdateRgn ) ; - Point pt = {0,0} ; - LocalToGlobal( &pt ) ; - OffsetRgn( formerUpdateRgn , -pt.h , -pt.v ) ; - SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ; - if ( !EmptyRgn( formerUpdateRgn ) ) - { - MacOffsetRgn( formerUpdateRgn , dx , dy ) ; - SectRgn( formerUpdateRgn , scrollRgn , formerUpdateRgn ) ; - InvalWindowRgn(rootWindow , formerUpdateRgn ) ; + + { + wxClientDC dc(this) ; + wxMacPortSetter helper(&dc) ; + + GetControlBounds( *m_peer, &scrollrect); + scrollrect.top += MacGetTopBorderSize() ; + scrollrect.left += MacGetLeftBorderSize() ; + scrollrect.bottom = scrollrect.top + height ; + scrollrect.right = scrollrect.left + width ; + + if ( rect ) + { + Rect r = { dc.YLOG2DEVMAC(rect->y) , dc.XLOG2DEVMAC(rect->x) , dc.YLOG2DEVMAC(rect->y + rect->height) , + dc.XLOG2DEVMAC(rect->x + rect->width) } ; + SectRect( &scrollrect , &r , &scrollrect ) ; + } + ScrollRect( &scrollrect , dx , dy , updateRgn ) ; } - InvalWindowRgn(rootWindow , updateRgn ) ; - DisposeRgn( updateRgn ) ; - DisposeRgn( formerUpdateRgn ) ; - DisposeRgn( scrollRgn ) ; + // ScrollWindowRect( (WindowRef) MacGetTopLevelWindowRef() , &scrollrect , dx , dy , kScrollWindowInvalidate, updateRgn ) ; #endif } @@ -2246,9 +2388,6 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) child->SetSize( x+dx, y+dy, w, h ); } } - -// TODO remove, was moved higher up Update() ; - } void wxWindowMac::MacOnScroll(wxScrollEvent &event ) @@ -2317,7 +2456,7 @@ void wxWindowMac::OnInternalIdle() void wxWindowMac::Raise() { #if TARGET_API_MAC_OSX - HIViewSetZOrder((ControlRef)m_macControl,kHIViewZOrderAbove, NULL) ; + HIViewSetZOrder(*m_peer,kHIViewZOrderAbove, NULL) ; #endif } @@ -2325,7 +2464,7 @@ void wxWindowMac::Raise() void wxWindowMac::Lower() { #if TARGET_API_MAC_OSX - HIViewSetZOrder((ControlRef)m_macControl,kHIViewZOrderBelow, NULL) ; + HIViewSetZOrder(*m_peer,kHIViewZOrderBelow, NULL) ; #endif } @@ -2386,9 +2525,39 @@ wxString wxWindowMac::MacGetToolTipString( wxPoint &pt ) void wxWindowMac::Update() { #if TARGET_API_MAC_OSX - HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ; + WindowRef window = (WindowRef)MacGetTopLevelWindowRef() ; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 + // 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 + HIViewSetNeedsDisplay( *m_peer , true ) ; + } #else - ::Draw1Control( (ControlRef) m_macControl ) ; + ::Draw1Control( *m_peer ) ; #endif } @@ -2408,9 +2577,9 @@ wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures ) Rect r ; RgnHandle visRgn = NewRgn() ; RgnHandle tempRgn = NewRgn() ; - if ( IsControlVisible( (ControlRef) m_macControl ) ) + if ( IsControlVisible( *m_peer ) ) { - GetControlBounds( (ControlRef) m_macControl , &r ) ; + GetControlBounds( *m_peer , &r ) ; if (! MacGetTopLevelWindow()->MacUsesCompositing() ) { MacRootWindowToWindow( &r.left , & r.top ) ; @@ -2534,7 +2703,7 @@ void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase) if ( MacGetTopLevelWindow()->MacUsesCompositing() == false ) { Rect bounds; - UMAGetControlBoundsInWindowCoords( (ControlRef)m_macControl, &bounds ); + UMAGetControlBoundsInWindowCoords( *m_peer, &bounds ); RgnHandle controlRgn = NewRgn(); RectRgn( controlRgn, &bounds ); //KO: This sets the ownUpdateRgn to the area of this control that is inside