X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/736fac3a51ed6e9c4ac906a731b9d35a349303e6..be5a51fb592f3fa2ba38ac6cd1e488d6d806058c:/src/mac/carbon/window.cpp diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index 88c4356480..7669c42d60 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 ; } @@ -681,22 +771,12 @@ void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size) UMASetControlTitle( (ControlRef) m_macControl , 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 ) @@ -1652,10 +1732,17 @@ bool wxWindowMac::Enable(bool enable) return FALSE; bool former = MacIsReallyEnabled() ; +#if TARGET_API_MAC_OSX if ( enable ) EnableControl( (ControlRef) m_macControl ) ; else DisableControl( (ControlRef) m_macControl ) ; +#else + if ( enable ) + ActivateControl( (ControlRef) m_macControl ) ; + else + DeactivateControl( (ControlRef) m_macControl ) ; +#endif if ( former != MacIsReallyEnabled() ) MacPropagateEnabledStateChanged() ; @@ -1757,7 +1844,11 @@ bool wxWindowMac::MacIsReallyShown() bool wxWindowMac::MacIsReallyEnabled() { +#if TARGET_API_MAC_OSX return IsControlEnabled( (ControlRef) m_macControl ) ; +#else + return IsControlActive( (ControlRef) m_macControl ) ; +#endif } bool wxWindowMac::MacIsReallyHilited() @@ -2183,57 +2274,44 @@ 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 + HIRect scrollrect = CGRectMake( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ; + if ( rect ) + { + HIRect scrollarea = CGRectMake( rect->x , rect->y , rect->width , rect->height) ; + scrollrect = CGRectIntersection( scrollrect , scrollarea ) ; + } + HIViewScrollRect ( (ControlRef) m_macControl , &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( (ControlRef) m_macControl, &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 } @@ -2399,7 +2477,37 @@ 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( (ControlRef) m_macControl , true ) ; + } #else ::Draw1Control( (ControlRef) m_macControl ) ; #endif