X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fe224552a9d5e4e652b39a815f1740dd7bf0b03a..cd66beb3439485e49fac308f54dc10fe01c92895:/src/mac/carbon/window.cpp diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index 8cf322afc2..0b6532ed84 100644 --- a/src/mac/carbon/window.cpp +++ b/src/mac/carbon/window.cpp @@ -11,61 +11,62 @@ #include "wx/wxprec.h" -#include "wx/menu.h" #include "wx/window.h" -#include "wx/dc.h" -#include "wx/dcclient.h" -#include "wx/utils.h" -#include "wx/app.h" -#include "wx/panel.h" -#include "wx/layout.h" -#include "wx/dialog.h" -#include "wx/scrolbar.h" -#include "wx/statbox.h" -#include "wx/button.h" -#include "wx/settings.h" -#include "wx/msgdlg.h" -#include "wx/frame.h" + +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/app.h" + #include "wx/utils.h" + #include "wx/panel.h" + #include "wx/frame.h" + #include "wx/dc.h" + #include "wx/dcclient.h" + #include "wx/button.h" + #include "wx/menu.h" + #include "wx/dialog.h" + #include "wx/settings.h" + #include "wx/msgdlg.h" + #include "wx/scrolbar.h" + #include "wx/statbox.h" + #include "wx/textctrl.h" + #include "wx/toolbar.h" + #include "wx/layout.h" + #include "wx/statusbr.h" + #include "wx/menuitem.h" + #include "wx/treectrl.h" + #include "wx/listctrl.h" +#endif + #include "wx/tooltip.h" -#include "wx/statusbr.h" -#include "wx/menuitem.h" #include "wx/spinctrl.h" -#include "wx/log.h" #include "wx/geometry.h" -#include "wx/textctrl.h" -#include "wx/toolbar.h" -#include "wx/dc.h" - -#if wxUSE_CARET - #include "wx/caret.h" +#if wxUSE_LISTCTRL + #include "wx/listctrl.h" #endif -#define MAC_SCROLLBAR_SIZE 15 -#define MAC_SMALL_SCROLLBAR_SIZE 11 - -#include "wx/mac/uma.h" - -#ifndef __DARWIN__ -#include -#include -#include -#include +#if wxUSE_TREECTRL + #include "wx/treectrl.h" #endif -#if TARGET_API_MAC_OSX -#ifndef __HIVIEW__ - #include +#if wxUSE_CARET + #include "wx/caret.h" #endif + +#if wxUSE_POPUPWIN + #include "wx/popupwin.h" #endif -#if wxUSE_DRAG_AND_DROP +#if wxUSE_DRAG_AND_DROP #include "wx/dnd.h" #endif -#include +#include "wx/mac/uma.h" + +#define MAC_SCROLLBAR_SIZE 15 +#define MAC_SMALL_SCROLLBAR_SIZE 11 -extern wxList wxPendingDelete; +#include #ifdef __WXUNIVERSAL__ IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase) @@ -76,9 +77,7 @@ extern wxList wxPendingDelete; BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase) EVT_NC_PAINT(wxWindowMac::OnNcPaint) EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground) -#if TARGET_API_MAC_OSX EVT_PAINT(wxWindowMac::OnPaint) -#endif EVT_SET_FOCUS(wxWindowMac::OnSetFocus) EVT_KILL_FOCUS(wxWindowMac::OnSetFocus) EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent) @@ -89,8 +88,6 @@ END_EVENT_TABLE() #define wxMAC_DEBUG_REDRAW 0 #endif -#define wxMAC_USE_THEME_BORDER 1 - // --------------------------------------------------------------------------- // Utility Routines to move between different coordinate systems // --------------------------------------------------------------------------- @@ -142,29 +139,26 @@ void wxMacWindowToNative( const wxWindow* window , Rect *rect ) // Carbon Events // --------------------------------------------------------------------------- -extern long wxMacTranslateKey(unsigned char key, unsigned char code) ; -pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor ) ; - -#if TARGET_API_MAC_OSX - -#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3 -enum -{ - kEventControlVisibilityChanged = 157 -}; -#endif - -#endif - static const EventTypeSpec eventList[] = { + { kEventClassCommand, kEventProcessCommand } , + { kEventClassCommand, kEventCommandUpdateStatus } , + + { kEventClassControl , kEventControlGetClickActivation } , { kEventClassControl , kEventControlHit } , -#if TARGET_API_MAC_OSX + { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } , + { kEventClassTextInput, kEventTextInputUpdateActiveInputArea } , + { kEventClassControl , kEventControlDraw } , + { kEventClassControl , kEventControlVisibilityChanged } , { kEventClassControl , kEventControlEnabledStateChanged } , { kEventClassControl , kEventControlHiliteChanged } , + + { kEventClassControl , kEventControlActivate } , + { kEventClassControl , kEventControlDeactivate } , + { kEventClassControl , kEventControlSetFocusPart } , { kEventClassService , kEventServiceGetTypes }, @@ -173,7 +167,6 @@ static const EventTypeSpec eventList[] = // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only // { kEventClassControl , kEventControlBoundsChanged } , -#endif } ; static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) @@ -189,21 +182,11 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl switch ( GetEventKind( event ) ) { -#if TARGET_API_MAC_OSX case kEventControlDraw : { RgnHandle updateRgn = NULL ; RgnHandle allocatedRgn = NULL ; wxRegion visRegion = thisWindow->MacGetVisibleRegion() ; - Rect controlBounds ; - - if ( ! thisWindow->GetPeer()->IsCompositing() ) - { - if ( thisWindow->GetPeer()->IsRootControl() ) - thisWindow->GetPeer()->GetRect( &controlBounds ) ; - else - GetControlBounds( thisWindow->GetPeer()->GetControlRef() , &controlBounds ) ; - } if ( cEvent.GetParameter(kEventParamRgnHandle, &updateRgn) != noErr ) { @@ -211,34 +194,18 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl } else { - if ( ! thisWindow->GetPeer()->IsCompositing() ) + 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 ) ; - 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() ) { @@ -263,57 +230,45 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl #endif { -#if wxMAC_USE_CORE_GRAPHICS 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 ) ; - -#if 0 - CGContextSetRGBFillColor( cgContext , 1.0 , 1.0 , 1.0 , 1.0 ) ; - CGContextFillRect(cgContext , CGRectMake( 0 , 0 , - controlBounds.right - controlBounds.left , - controlBounds.bottom - controlBounds.top ) ); -#endif - - } - + CGContextRef cgContext = NULL ; + OSStatus err = cEvent.GetParameter(kEventParamCGContextRef, &cgContext) ; + wxASSERT_MSG( err == noErr , wxT("Unable to retrieve CGContextRef") ) ; thisWindow->MacSetCGContextRef( cgContext ) ; { wxMacCGContextStateSaver sg( cgContext ) ; -#endif + float alpha = 1.0 ; + { + wxWindow* iter = thisWindow ; + while ( iter ) + { + alpha *= (float) iter->GetTransparent()/255.0 ; + if ( iter->IsTopLevel() ) + iter = NULL ; + else + iter = iter->GetParent() ; + } + } + CGContextSetAlpha( cgContext , alpha ) ; + + if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) + { + HIRect bounds; + HIViewGetBounds( controlRef, &bounds ); + CGContextClearRect( cgContext, bounds ); + } + + + if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) ) result = noErr ; -#if wxMAC_USE_CORE_GRAPHICS thisWindow->MacSetCGContextRef( NULL ) ; } if ( created ) CGContextRelease( cgContext ) ; -#endif } if ( allocatedRgn ) @@ -326,13 +281,25 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl break ; case kEventControlEnabledStateChanged : - thisWindow->MacEnabledStateChanged() ; + thisWindow->MacEnabledStateChanged(); break ; case kEventControlHiliteChanged : thisWindow->MacHiliteChanged() ; break ; + + case kEventControlActivate : + case kEventControlDeactivate : + // FIXME: we should have a virtual function for this! +#if wxUSE_TREECTRL + if ( thisWindow->IsKindOf( CLASSINFO( wxTreeCtrl ) ) ) + thisWindow->Refresh(); #endif +#if wxUSE_LISTCTRL + if ( thisWindow->IsKindOf( CLASSINFO( wxListCtrl ) ) ) + thisWindow->Refresh(); +#endif + break ; // we emulate this event under Carbon CFM case kEventControlSetFocusPart : @@ -340,11 +307,12 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl Boolean focusEverything = false ; ControlPartCode controlPart = cEvent.GetParameter(kEventParamControlPart , typeControlPartCode ); -#ifdef __WXMAC_OSX__ if ( cEvent.GetParameter(kEventParamControlFocusEverything , &focusEverything ) == noErr ) { } -#endif + + if ( thisWindow->MacIsUserPane() ) + result = noErr ; if ( controlPart == kControlFocusNoPart ) { @@ -379,9 +347,6 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl event.SetEventObject(thisWindow); thisWindow->GetEventHandler()->ProcessEvent(event) ; } - - if ( thisWindow->MacIsUserPane() ) - result = noErr ; } break ; @@ -389,6 +354,18 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl result = thisWindow->MacControlHit( handler , event ) ; break ; + case kEventControlGetClickActivation : + { + // fix to always have a proper activation for DataBrowser controls (stay in bkgnd otherwise) + WindowRef owner = cEvent.GetParameter(kEventParamWindowRef); + if ( !IsWindowActive(owner) ) + { + cEvent.SetParameter(kEventParamClickActivation,(UInt32) kActivateAndIgnoreClick) ; + result = noErr ; + } + } + break ; + default : break ; } @@ -396,7 +373,10 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl return result ; } -static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +static pascal OSStatus +wxMacWindowServiceEventHandler(EventHandlerCallRef WXUNUSED(handler), + EventRef event, + void *data) { OSStatus result = eventNotHandledErr ; @@ -448,9 +428,13 @@ static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handl 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() ) ) ; + PasteboardRef pasteboard = cEvent.GetParameter( kEventParamPasteboardRef, typePasteboardRef ); + verify_noerr( PasteboardClear( pasteboard ) ) ; + PasteboardSynchronize( pasteboard ); + // TODO add proper conversion + CFDataRef data = CFDataCreate( kCFAllocatorDefault, (const UInt8*)val.c_str(), val.length() ); + PasteboardPutItemFlavor( pasteboard, (PasteboardItemID) 1, CFSTR("com.apple.traditional-mac-plain-text"), data, 0); + CFRelease( data ); result = noErr ; } break ; @@ -458,22 +442,34 @@ static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handl 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 ; - + PasteboardRef pasteboard = cEvent.GetParameter( kEventParamPasteboardRef, typePasteboardRef ); + PasteboardSynchronize( pasteboard ); + ItemCount itemCount; + verify_noerr( PasteboardGetItemCount( pasteboard, &itemCount ) ); + for( UInt32 itemIndex = 1; itemIndex <= itemCount; itemIndex++ ) + { + PasteboardItemID itemID; + if ( PasteboardGetItemIdentifier( pasteboard, itemIndex, &itemID ) == noErr ) + { + CFDataRef flavorData = NULL; + if ( PasteboardCopyItemFlavorData( pasteboard, itemID, CFSTR("com.apple.traditional-mac-plain-text"), &flavorData ) == noErr ) + { + CFIndex flavorDataSize = CFDataGetLength( flavorData ); + char *content = new char[flavorDataSize+1] ; + memcpy( content, CFDataGetBytePtr( flavorData ), flavorDataSize ); + content[flavorDataSize]=0; + CFRelease( flavorData ); #if wxUSE_UNICODE - textCtrl->WriteText( wxString( content , wxConvLocal ) ); + textCtrl->WriteText( wxString( content , wxConvLocal ) ); #else - textCtrl->WriteText( wxString( content ) ) ; + textCtrl->WriteText( wxString( content ) ) ; #endif - delete[] content ; - result = noErr ; + delete[] content ; + result = noErr ; + } + } + } } break ; @@ -484,161 +480,206 @@ static pascal OSStatus wxMacWindowServiceEventHandler( EventHandlerCallRef handl return result ; } -pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +pascal OSStatus wxMacUnicodeTextEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ; - EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ; - wxTheApp->MacSetCurrentEvent( event , handler ) ; OSStatus result = eventNotHandledErr ; + wxWindowMac* focus = (wxWindowMac*) data ; - switch ( GetEventClass( event ) ) + wchar_t* uniChars = NULL ; + UInt32 when = EventTimeToTicks( GetEventTime( event ) ) ; + + UniChar* charBuf = NULL; + ByteCount dataSize = 0 ; + int numChars = 0 ; + UniChar buf[2] ; + if ( GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, 0 , &dataSize, NULL ) == noErr ) { - case kEventClassControl : - result = wxMacWindowControlEventHandler( handler, event, data ) ; - break ; + numChars = dataSize / sizeof( UniChar) + 1; + charBuf = buf ; - case kEventClassService : - result = wxMacWindowServiceEventHandler( handler, event , data ) ; + if ( (size_t) numChars * 2 > sizeof(buf) ) + charBuf = new UniChar[ numChars ] ; + else + charBuf = buf ; + + uniChars = new wchar_t[ numChars ] ; + GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText, NULL, dataSize , NULL , charBuf ) ; + charBuf[ numChars - 1 ] = 0; +#if SIZEOF_WCHAR_T == 2 + uniChars = (wchar_t*) charBuf ; +/* memcpy( uniChars , charBuf , numChars * 2 ) ;*/ // is there any point in copying charBuf over itself? (in fact, memcpy isn't even guaranteed to work correctly if the source and destination ranges overlap...) +#else + // the resulting string will never have more chars than the utf16 version, so this is safe + wxMBConvUTF16 converter ; + numChars = converter.MB2WC( uniChars , (const char*)charBuf , numChars ) ; +#endif + } + + switch ( GetEventKind( event ) ) + { + case kEventTextInputUpdateActiveInputArea : + { + // An IME input event may return several characters, but we need to send one char at a time to + // EVT_CHAR + for (int pos=0 ; pos < numChars ; pos++) + { + WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ; + WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ; + wxTheApp->MacSetCurrentEvent( event , handler ) ; + + UInt32 message = uniChars[pos] < 128 ? (char)uniChars[pos] : '?'; +/* + NB: faking a charcode here is problematic. The kEventTextInputUpdateActiveInputArea event is sent + multiple times to update the active range during inline input, so this handler will often receive + uncommited text, which should usually not trigger side effects. It might be a good idea to check the + kEventParamTextInputSendFixLen parameter and verify if input is being confirmed (see CarbonEvents.h). + On the other hand, it can be useful for some applications to react to uncommitted text (for example, + to update a status display), as long as it does not disrupt the inline input session. Ideally, wx + should add new event types to support advanced text input. For now, I would keep things as they are. + + However, the code that was being used caused additional problems: + UInt32 message = (0 << 8) + ((char)uniChars[pos] ); + Since it simply truncated the unichar to the last byte, it ended up causing weird bugs with inline + input, such as switching to another field when one attempted to insert the character U+4E09 (the kanji + for "three"), because it was truncated to 09 (kTabCharCode), which was later "converted" to WXK_TAB + (still 09) in wxMacTranslateKey; or triggering the default button when one attempted to insert U+840D + (the kanji for "name"), which got truncated to 0D and interpreted as a carriage return keypress. + Note that even single-byte characters could have been misinterpreted, since MacRoman charcodes only + overlap with Unicode within the (7-bit) ASCII range. + But simply passing a NUL charcode would disable text updated events, because wxTextCtrl::OnChar checks + for codes within a specific range. Therefore I went for the solution seen above, which keeps ASCII + characters as they are and replaces the rest with '?', ensuring that update events are triggered. + It would be better to change wxTextCtrl::OnChar to look at the actual unicode character instead, but + I don't have time to look into that right now. + -- CL +*/ + if ( wxTheApp->MacSendCharEvent( + focus , message , 0 , when , 0 , 0 , uniChars[pos] ) ) + { + result = noErr ; + } + + wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ; + } + } break ; + case kEventTextInputUnicodeForKeyEvent : + { + UInt32 keyCode, modifiers ; + Point point ; + EventRef rawEvent ; + unsigned char charCode ; + + GetEventParameter( event, kEventParamTextInputSendKeyboardEvent, typeEventRef, NULL, sizeof(rawEvent), NULL, &rawEvent ) ; + GetEventParameter( rawEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &charCode ); + GetEventParameter( rawEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &keyCode ); + GetEventParameter( rawEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers ); + GetEventParameter( rawEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &point ); + + UInt32 message = (keyCode << 8) + charCode; + + // An IME input event may return several characters, but we need to send one char at a time to + // EVT_CHAR + for (int pos=0 ; pos < numChars ; pos++) + { + WXEVENTREF formerEvent = wxTheApp->MacGetCurrentEvent() ; + WXEVENTHANDLERCALLREF formerHandler = wxTheApp->MacGetCurrentEventHandlerCallRef() ; + wxTheApp->MacSetCurrentEvent( event , handler ) ; - default : + if ( wxTheApp->MacSendCharEvent( + focus , message , modifiers , when , point.h , point.v , uniChars[pos] ) ) + { + result = noErr ; + } + + wxTheApp->MacSetCurrentEvent( formerEvent , formerHandler ) ; + } + } + break; + default: break ; } - wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ; + delete [] uniChars ; + if ( charBuf != buf ) + delete [] charBuf ; return result ; } -DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler ) - -#if !TARGET_API_MAC_OSX - -// --------------------------------------------------------------------------- -// UserPane events for non OSX builds -// --------------------------------------------------------------------------- - -static pascal void wxMacControlUserPaneDrawProc(ControlRef control, SInt16 part) +static pascal OSStatus +wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler), + EventRef event, + void *data) { - wxWindow * win = wxFindControlFromMacControl(control) ; - if ( win ) - win->MacControlUserPaneDrawProc(part) ; -} -wxMAC_DEFINE_PROC_GETTER( ControlUserPaneDrawUPP , wxMacControlUserPaneDrawProc ) ; + OSStatus result = eventNotHandledErr ; + wxWindowMac* focus = (wxWindowMac*) data ; -static pascal ControlPartCode wxMacControlUserPaneHitTestProc(ControlRef control, Point where) -{ - wxWindow * win = wxFindControlFromMacControl(control) ; - if ( win ) - return win->MacControlUserPaneHitTestProc(where.h , where.v) ; - else - return kControlNoPart ; -} -wxMAC_DEFINE_PROC_GETTER( ControlUserPaneHitTestUPP , wxMacControlUserPaneHitTestProc ) ; + HICommand command ; -static pascal ControlPartCode wxMacControlUserPaneTrackingProc(ControlRef control, Point startPt, ControlActionUPP actionProc) -{ - wxWindow * win = wxFindControlFromMacControl(control) ; - if ( win ) - return win->MacControlUserPaneTrackingProc( startPt.h , startPt.v , (void*) actionProc) ; - else - return kControlNoPart ; -} -wxMAC_DEFINE_PROC_GETTER( ControlUserPaneTrackingUPP , wxMacControlUserPaneTrackingProc ) ; + wxMacCarbonEvent cEvent( event ) ; + cEvent.GetParameter(kEventParamDirectObject,typeHICommand,&command) ; -static pascal void wxMacControlUserPaneIdleProc(ControlRef control) -{ - wxWindow * win = wxFindControlFromMacControl(control) ; - if ( win ) - win->MacControlUserPaneIdleProc() ; -} -wxMAC_DEFINE_PROC_GETTER( ControlUserPaneIdleUPP , wxMacControlUserPaneIdleProc ) ; + wxMenuItem* item = NULL ; + wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ; + int id = wxMacCommandToId( command.commandID ) ; -static pascal ControlPartCode wxMacControlUserPaneKeyDownProc(ControlRef control, SInt16 keyCode, SInt16 charCode, SInt16 modifiers) -{ - wxWindow * win = wxFindControlFromMacControl(control) ; - if ( win ) - return win->MacControlUserPaneKeyDownProc(keyCode,charCode,modifiers) ; - else - return kControlNoPart ; -} -wxMAC_DEFINE_PROC_GETTER( ControlUserPaneKeyDownUPP , wxMacControlUserPaneKeyDownProc ) ; + if ( item ) + { + wxASSERT( itemMenu != NULL ) ; -static pascal void wxMacControlUserPaneActivateProc(ControlRef control, Boolean activating) -{ - wxWindow * win = wxFindControlFromMacControl(control) ; - if ( win ) - win->MacControlUserPaneActivateProc(activating) ; -} -wxMAC_DEFINE_PROC_GETTER( ControlUserPaneActivateUPP , wxMacControlUserPaneActivateProc ) ; + switch ( cEvent.GetKind() ) + { + case kEventProcessCommand : + result = itemMenu->MacHandleCommandProcess( item, id, focus ); + break ; -static pascal ControlPartCode wxMacControlUserPaneFocusProc(ControlRef control, ControlFocusPart action) -{ - wxWindow * win = wxFindControlFromMacControl(control) ; - if ( win ) - return win->MacControlUserPaneFocusProc(action) ; - else - return kControlNoPart ; -} -wxMAC_DEFINE_PROC_GETTER( ControlUserPaneFocusUPP , wxMacControlUserPaneFocusProc ) ; + case kEventCommandUpdateStatus: + result = itemMenu->MacHandleCommandUpdateStatus( item, id, focus ); + break ; -static pascal void wxMacControlUserPaneBackgroundProc(ControlRef control, ControlBackgroundPtr info) -{ - wxWindow * win = wxFindControlFromMacControl(control) ; - if ( win ) - win->MacControlUserPaneBackgroundProc(info) ; + default : + break ; + } + } + return result ; } -wxMAC_DEFINE_PROC_GETTER( ControlUserPaneBackgroundUPP , wxMacControlUserPaneBackgroundProc ) ; -void wxWindowMac::MacControlUserPaneDrawProc(wxInt16 part) +pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { - int x = 0 , y = 0; - RgnHandle rgn = NewRgn() ; - GetClip( rgn ) ; - MacWindowToRootWindow( &x,&y ) ; - OffsetRgn( rgn , -x , -y ) ; - wxMacWindowStateSaver sv( this ) ; - SectRgn( rgn , (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , rgn ) ; - MacDoRedraw( rgn , 0 ) ; - DisposeRgn( rgn ) ; -} + EventRef formerEvent = (EventRef) wxTheApp->MacGetCurrentEvent() ; + EventHandlerCallRef formerEventHandlerCallRef = (EventHandlerCallRef) wxTheApp->MacGetCurrentEventHandlerCallRef() ; + wxTheApp->MacSetCurrentEvent( event , handler ) ; + OSStatus result = eventNotHandledErr ; -wxInt16 wxWindowMac::MacControlUserPaneHitTestProc(wxInt16 x, wxInt16 y) -{ - return kControlNoPart ; -} + switch ( GetEventClass( event ) ) + { + case kEventClassCommand : + result = wxMacWindowCommandEventHandler( handler , event , data ) ; + break ; -wxInt16 wxWindowMac::MacControlUserPaneTrackingProc(wxInt16 x, wxInt16 y, void* actionProc) -{ - return kControlNoPart ; -} + case kEventClassControl : + result = wxMacWindowControlEventHandler( handler, event, data ) ; + break ; -void wxWindowMac::MacControlUserPaneIdleProc() -{ -} + case kEventClassService : + result = wxMacWindowServiceEventHandler( handler, event , data ) ; + break ; -wxInt16 wxWindowMac::MacControlUserPaneKeyDownProc(wxInt16 keyCode, wxInt16 charCode, wxInt16 modifiers) -{ - return kControlNoPart ; -} + case kEventClassTextInput : + result = wxMacUnicodeTextEventHandler( handler , event , data ) ; + break ; -void wxWindowMac::MacControlUserPaneActivateProc(bool activating) -{ -} + default : + break ; + } -wxInt16 wxWindowMac::MacControlUserPaneFocusProc(wxInt16 action) -{ - if ( AcceptsFocus() ) - return 1 ; - else - return kControlNoPart ; -} + wxTheApp->MacSetCurrentEvent( formerEvent, formerEventHandlerCallRef ) ; -void wxWindowMac::MacControlUserPaneBackgroundProc(void* info) -{ + return result ; } -#endif +DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacWindowEventHandler ) // --------------------------------------------------------------------------- // Scrollbar Tracking for all @@ -727,21 +768,16 @@ void wxWindowMac::Init() { m_peer = NULL ; m_frozenness = 0 ; - -#if WXWIN_COMPATIBILITY_2_4 - m_backgroundTransparent = false; -#endif - -#if wxMAC_USE_CORE_GRAPHICS + m_macAlpha = 255 ; m_cgContextRef = NULL ; -#endif // as all windows are created with WS_VISIBLE style... m_isShown = true; m_hScrollBar = NULL ; m_vScrollBar = NULL ; - m_macBackgroundBrush = wxNullBrush ; + m_hScrollBarAlwaysShown = false; + m_vScrollBarAlwaysShown = false; m_macIsUserPane = true; m_clipChildren = false ; @@ -751,7 +787,6 @@ void wxWindowMac::Init() wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); } -// Destructor wxWindowMac::~wxWindowMac() { SendDestroyEvent(); @@ -772,7 +807,7 @@ wxWindowMac::~wxWindowMac() break; } } -#endif // __WXUNIVERSAL__ +#endif // destroy children before destroying this window itself DestroyChildren(); @@ -780,11 +815,11 @@ wxWindowMac::~wxWindowMac() // wxRemoveMacControlAssociation( this ) ; // If we delete an item, we should initialize the parent panel, // because it could now be invalid. - wxWindow *parent = GetParent() ; - if ( parent ) + wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow); + if ( tlw ) { - if (parent->GetDefaultItem() == (wxButton*) this) - parent->SetDefaultItem(NULL); + if ( tlw->GetDefaultItem() == (wxButton*) this) + tlw->SetDefaultItem(NULL); } if ( m_peer && m_peer->Ok() ) @@ -800,12 +835,14 @@ wxWindowMac::~wxWindowMac() if ( g_MacLastWindow == this ) g_MacLastWindow = NULL ; - wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ; +#ifndef __WXUNIVERSAL__ + wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( (wxWindow*)this ) , wxFrame ) ; if ( frame ) { if ( frame->GetLastFocus() == this ) frame->SetLastFocus( NULL ) ; } +#endif // delete our drop target if we've got one #if wxUSE_DRAG_AND_DROP @@ -830,28 +867,15 @@ void wxWindowMac::MacInstallEventHandler( WXWidget control ) InstallControlEventHandler( (ControlRef)control , GetwxMacWindowEventHandlerUPP(), GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_macControlEventHandler); - -#if !TARGET_API_MAC_OSX - if ( (ControlRef) control == m_peer->GetControlRef() ) - { - m_peer->SetData(kControlEntireControl, kControlUserPaneDrawProcTag, GetwxMacControlUserPaneDrawProc()) ; - m_peer->SetData(kControlEntireControl, kControlUserPaneHitTestProcTag, GetwxMacControlUserPaneHitTestProc()) ; - m_peer->SetData(kControlEntireControl, kControlUserPaneTrackingProcTag, GetwxMacControlUserPaneTrackingProc()) ; - m_peer->SetData(kControlEntireControl, kControlUserPaneIdleProcTag, GetwxMacControlUserPaneIdleProc()) ; - m_peer->SetData(kControlEntireControl, kControlUserPaneKeyDownProcTag, GetwxMacControlUserPaneKeyDownProc()) ; - m_peer->SetData(kControlEntireControl, kControlUserPaneActivateProcTag, GetwxMacControlUserPaneActivateProc()) ; - m_peer->SetData(kControlEntireControl, kControlUserPaneFocusProcTag, GetwxMacControlUserPaneFocusProc()) ; - m_peer->SetData(kControlEntireControl, kControlUserPaneBackgroundProcTag, GetwxMacControlUserPaneBackgroundProc()) ; - } -#endif } // Constructor -bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) +bool wxWindowMac::Create(wxWindowMac *parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") ); @@ -873,19 +897,19 @@ bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id, | kControlHandlesTracking | kControlSupportsFocus | kControlWantsActivate - | kControlWantsIdle - ; + | kControlWantsIdle ; m_peer = new wxMacControl(this) ; - ::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , m_peer->GetControlRefAddr() ); + OSStatus err =::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , m_peer->GetControlRefAddr() ); + verify_noerr( err ); MacPostControlCreate(pos, size) ; } #ifndef __WXUNIVERSAL__ // Don't give scrollbars to wxControls unless they ask for them - if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) || - (IsKindOf(CLASSINFO(wxControl)) && ( style & wxHSCROLL || style & wxVSCROLL))) + if ( (! IsKindOf(CLASSINFO(wxControl)) && ! IsKindOf(CLASSINFO(wxStatusBar))) + || (IsKindOf(CLASSINFO(wxControl)) && ((style & wxHSCROLL) || (style & wxVSCROLL)))) { MacCreateScrollBars( style ) ; } @@ -905,12 +929,12 @@ void wxWindowMac::MacChildAdded() m_hScrollBar->Raise() ; } -void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size) +void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size) { wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ; - m_peer->SetReference( (long) this ) ; - GetParent()->AddChild(this); + m_peer->SetReference( (URefCon) this ) ; + GetParent()->AddChild( this ); MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ); @@ -922,10 +946,10 @@ void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size) // adjust font, controlsize etc DoSetWindowVariant( m_windowVariant ) ; - m_peer->SetLabel( wxStripMenuCodes(m_label) ) ; + m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; if (!m_macIsUserPane) - SetInitialBestSize(size); + SetInitialSize(size); SetCursor( *wxSTANDARD_CURSOR ) ; } @@ -961,17 +985,9 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) break ; case wxWINDOW_VARIANT_MINI : - if (UMAGetSystemVersion() >= 0x1030 ) - { - // not always defined in the headers - size = 3 ; - themeFont = 109 ; - } - else - { - size = kControlSizeSmall; - themeFont = kThemeSmallSystemFont ; - } + // not always defined in the headers + size = 3 ; + themeFont = 109 ; break ; case wxWINDOW_VARIANT_LARGE : @@ -994,12 +1010,14 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) void wxWindowMac::MacUpdateControlFont() { m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; - Refresh() ; + // do not trigger refreshes upon invisible and possible partly created objects + if ( MacIsReallyShown() ) + Refresh() ; } bool wxWindowMac::SetFont(const wxFont& font) { - bool retval = wxWindowBase::SetFont( font ) ; + bool retval = wxWindowBase::SetFont( font ); MacUpdateControlFont() ; @@ -1008,10 +1026,10 @@ bool wxWindowMac::SetFont(const wxFont& font) bool wxWindowMac::SetForegroundColour(const wxColour& col ) { - bool retval = wxWindowBase::SetForegroundColour(col); + bool retval = wxWindowBase::SetForegroundColour( col ); if (retval) - MacUpdateControlFont() ; + MacUpdateControlFont(); return retval; } @@ -1021,38 +1039,31 @@ bool wxWindowMac::SetBackgroundColour(const wxColour& col ) if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol ) return false ; - wxBrush brush ; - wxColour newCol(GetBackgroundColour()); - if ( newCol == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) ) - brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ; - else if ( newCol == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) ) - brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ; - else - brush.SetColour( newCol ) ; - - MacSetBackgroundBrush( brush ) ; - - MacUpdateControlFont() ; + m_peer->SetBackgroundColour( col ) ; return true ; } -void wxWindowMac::MacSetBackgroundBrush( const wxBrush &brush ) -{ - m_macBackgroundBrush = brush ; - m_peer->SetBackground( brush ) ; -} - bool wxWindowMac::MacCanFocus() const { - // 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 ; - m_peer->GetFeatures( &features ) ; + // TODO : evaluate performance hits by looking up this value, eventually cache the results for a 1 sec or so + // CAUTION : the value returned currently is 0 or 2, I've also found values of 1 having the same meaning, + // but the value range is nowhere documented + Boolean keyExistsAndHasValidFormat ; + CFIndex fullKeyboardAccess = CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) , + kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat ); - return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ; + if ( keyExistsAndHasValidFormat && fullKeyboardAccess > 0 ) + { + return true ; + } + else + { + UInt32 features = 0 ; + m_peer->GetFeatures( &features ) ; + + return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ; + } } void wxWindowMac::SetFocus() @@ -1070,41 +1081,7 @@ void wxWindowMac::SetFocus() if ( err == errCouldntSetFocus ) return ; - // enable for patch 1376506 - perhaps? (Stefan's version) -#if 1 SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() ); -#endif - -#if !TARGET_API_MAC_OSX - // emulate carbon events when running under CarbonLib where they are not natively available - if ( former ) - { - EventRef evRef = NULL ; - verify_noerr( MacCreateEvent( NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) , kEventAttributeUserEvent , - &evRef ) ); - - wxMacCarbonEvent cEvent( evRef ) ; - cEvent.SetParameter( kEventParamDirectObject , (ControlRef) former->GetHandle() ) ; - cEvent.SetParameter(kEventParamControlPart , typeControlPartCode , kControlFocusNoPart ) ; - - wxMacWindowEventHandler( NULL , evRef , former ) ; - ReleaseEvent(evRef) ; - } - - // send new focus event - { - EventRef evRef = NULL ; - verify_noerr( MacCreateEvent( NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) , kEventAttributeUserEvent , - &evRef ) ); - - wxMacCarbonEvent cEvent( evRef ) ; - cEvent.SetParameter( kEventParamDirectObject , (ControlRef) GetHandle() ) ; - cEvent.SetParameter(kEventParamControlPart , typeControlPartCode , kControlFocusNextPart ) ; - - wxMacWindowEventHandler( NULL , evRef , this ) ; - ReleaseEvent(evRef) ; - } -#endif } void wxWindowMac::DoCaptureMouse() @@ -1112,7 +1089,7 @@ void wxWindowMac::DoCaptureMouse() wxApp::s_captureWindow = this ; } -wxWindow* wxWindowBase::GetCapture() +wxWindow * wxWindowBase::GetCapture() { return wxApp::s_captureWindow ; } @@ -1132,23 +1109,25 @@ void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget) m_dropTarget = pDropTarget; if ( m_dropTarget != NULL ) { - // TODO + // TODO: } } #endif -// Old style file-manager drag&drop -void wxWindowMac::DragAcceptFiles(bool accept) +// Old-style File Manager Drag & Drop +void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept)) { - // TODO + // TODO: } // Returns the size of the native control. In the case of the toplevel window // this is the content area root control -void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y, - int& w, int& h) const +void wxWindowMac::MacGetPositionAndSizeFromControl(int& WXUNUSED(x), + int& WXUNUSED(y), + int& WXUNUSED(w), + int& WXUNUSED(h)) const { wxFAIL_MSG( wxT("Not currently supported") ) ; } @@ -1161,19 +1140,14 @@ bool wxWindowMac::MacGetBoundsForControl( int& x, int& y, 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; y = (int)pos.y; - // todo the default calls may be used as soon as PostCreateControl Is moved here + + // TODO: the default calls may be used as soon as PostCreateControl Is moved here w = wxMax(size.x, 0) ; // WidthDefault( size.x ); h = wxMax(size.y, 0) ; // HeightDefault( size.y ) ; - if ( !isCompositing ) - GetParent()->MacWindowToRootWindow( &x , &y ) ; - x += MacGetLeftBorderSize() ; y += MacGetTopBorderSize() ; w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ; @@ -1243,24 +1217,21 @@ void wxWindowMac::DoGetPosition(int *x, int *y) const void wxWindowMac::DoScreenToClient(int *x, int *y) const { WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; + wxCHECK_RET( window , wxT("TopLevel Window missing") ) ; - wxCHECK_RET( window , wxT("TopLevel Window Missing") ) ; + Point localwhere = { 0, 0 } ; - { - Point localwhere = {0, 0} ; - - if (x) - localwhere.h = *x ; - if (y) - localwhere.v = *y ; + if (x) + localwhere.h = *x ; + if (y) + localwhere.v = *y ; - QDGlobalToLocalPoint( GetWindowPort( window ) , &localwhere ) ; + wxMacGlobalToLocal( window , &localwhere ) ; - if (x) - *x = localwhere.h ; - if (y) - *y = localwhere.v ; - } + if (x) + *x = localwhere.h ; + if (y) + *y = localwhere.v ; MacRootWindowToWindow( x , y ) ; @@ -1274,7 +1245,7 @@ void wxWindowMac::DoScreenToClient(int *x, int *y) const void wxWindowMac::DoClientToScreen(int *x, int *y) const { WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; - wxCHECK_RET( window , wxT("TopLevel Window Missing") ) ; + wxCHECK_RET( window , wxT("TopLevel window missing") ) ; wxPoint origin = GetClientAreaOrigin() ; if (x) @@ -1284,20 +1255,18 @@ void wxWindowMac::DoClientToScreen(int *x, int *y) const MacWindowToRootWindow( x , y ) ; - { - Point localwhere = { 0,0 }; - if (x) - localwhere.h = * x ; - if (y) - localwhere.v = * y ; + Point localwhere = { 0, 0 }; + if (x) + localwhere.h = *x ; + if (y) + localwhere.v = *y ; - QDLocalToGlobalPoint( GetWindowPort( window ) , &localwhere ) ; + wxMacLocalToGlobal( window, &localwhere ) ; - if (x) - *x = localwhere.h ; - if (y) - *y = localwhere.v ; - } + if (x) + *x = localwhere.h ; + if (y) + *y = localwhere.v ; } void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const @@ -1325,6 +1294,7 @@ void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const { wxPoint pt ; + if (x) pt.x = *x ; if (y) @@ -1446,7 +1416,7 @@ wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const // structure is in parent coordinates, but we only need width and height, so it's ok sizeTotal.x += (structure.right - structure.left) - (content.right - content.left) ; - sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top ) ; + sizeTotal.y += (structure.bottom - structure.top) - (content.bottom - content.top) ; } DisposeRgn( rgn ) ; @@ -1487,10 +1457,10 @@ void wxWindowMac::DoGetClientSize( int *x, int *y ) const bool wxWindowMac::SetCursor(const wxCursor& cursor) { - if (m_cursor == cursor) + if (m_cursor.IsSameAs(cursor)) return false; - if (wxNullCursor == cursor) + if (!cursor.IsOk()) { if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) ) return false ; @@ -1508,22 +1478,27 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) { wxTopLevelWindowMac *tlw = MacGetTopLevelWindow() ; WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ; - CGrafPtr savePort ; - Boolean swapped = QDSwapPort( GetWindowPort( window ) , &savePort ) ; - - // TODO If we ever get a GetCurrentEvent.. replacement for the mouse - // position, use it... - Point pt ; - GetMouse( &pt ) ; ControlPartCode part ; ControlRef control ; - control = wxMacFindControlUnderMouse( tlw , pt , window , &part ) ; + Point pt ; + #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 + HIPoint hiPoint ; + HIGetMousePosition(kHICoordSpaceWindow, window, &hiPoint); + pt.h = hiPoint.x; + pt.v = hiPoint.y; + #else + GetGlobalMouse( &pt ); + int x = pt.h; + int y = pt.v; + ScreenToClient(&x, &y); + pt.h = x; + pt.v = y; +#endif + control = FindControlUnderMouse( pt , window , &part ) ; if ( control ) mouseWin = wxFindControlFromMacControl( control ) ; - if ( swapped ) - QDSwapPort( savePort , NULL ) ; } if ( mouseWin == this && !wxIsBusy() ) @@ -1535,10 +1510,11 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) #if wxUSE_MENUS bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) { - menu->SetInvokingWindow(this); +#ifndef __WXUNIVERSAL__ + menu->SetInvokingWindow((wxWindow*)this); menu->UpdateUI(); - if ( x == -1 && y == -1 ) + if ( x == wxDefaultCoord && y == wxDefaultCoord ) { wxPoint mouse = wxGetMousePosition(); x = mouse.x; @@ -1553,21 +1529,29 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() , y, x, 0) ; if ( HiWord(menuResult) != 0 ) { - MenuCommand id ; - GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &id ) ; + MenuCommand macid; + GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &macid ); + int id = wxMacCommandToId( macid ); wxMenuItem* item = NULL ; wxMenu* realmenu ; - item = menu->FindItem(id, &realmenu) ; - if (item->IsCheckable()) - item->Check( !item->IsChecked() ) ; + item = menu->FindItem( id, &realmenu ) ; + if ( item ) + { + if (item->IsCheckable()) + item->Check( !item->IsChecked() ) ; - menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; + menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; + } } menu->MacAfterDisplay( true ) ; - menu->SetInvokingWindow(NULL); + menu->SetInvokingWindow( NULL ); return true; +#else + // actually this shouldn't be called, because universal is having its own implementation + return false; +#endif } #endif @@ -1603,126 +1587,26 @@ void wxWindowMac::MacInvalidateBorders() if ( outerBorder == 0 ) return ; - // 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() , - updateOuter = NewRgn() ; - - // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon - Rect rect ; - m_peer->GetRect( &rect ) ; - RectRgn( updateInner, &rect ) ; - InsetRect( &rect , -outerBorder , -outerBorder ) ; - RectRgn( updateOuter, &rect ) ; - DiffRgn( updateOuter, updateInner , updateOuter ) ; - -#ifdef __WXMAC_OSX__ - GetParent()->m_peer->SetNeedsDisplay( updateOuter ) ; -#else - WindowRef tlw = (WindowRef) MacGetTopLevelWindowRef() ; - if ( tlw ) - InvalWindowRgn( tlw , updateOuter ) ; -#endif - - DisposeRgn(updateOuter) ; - DisposeRgn(updateInner) ; - -#if 0 - RgnHandle updateInner = NewRgn() , updateOuter = NewRgn() ; - RectRgn( updateInner , &rect ) ; - InsetRect( &rect , -4 , -4 ) ; - RectRgn( updateOuter , &rect ) ; - DiffRgn( updateOuter , updateInner , updateOuter ) ; - wxPoint parent(0, 0); - GetParent()->MacWindowToRootWindow( &parent.x , &parent.y ) ; - parent -= GetParent()->GetClientAreaOrigin() ; - OffsetRgn( updateOuter , -parent.x , -parent.y ) ; - GetParent()->m_peer->SetNeedsDisplay( true , updateOuter ) ; - DisposeRgn(updateOuter) ; - DisposeRgn(updateInner) ; -#endif - -#if 0 - if ( m_peer ) - { - // deleting a window while it is shown invalidates the region occupied by border or - // focus - - if ( IsShown() && ( outerBorder > 0 ) ) - { - // as the borders are drawn on the parent we have to properly invalidate all these areas - RgnHandle updateInner = NewRgn() , updateOuter = NewRgn() , updateTotal = NewRgn() ; - - Rect rect ; - - m_peer->GetRect( &rect ) ; - RectRgn( updateInner , &rect ) ; - InsetRect( &rect , -outerBorder , -outerBorder ) ; - RectRgn( updateOuter , &rect ) ; - DiffRgn( updateOuter , updateInner ,updateOuter ) ; - wxPoint parent(0, 0); - GetParent()->MacWindowToRootWindow( &parent.x , &parent.y ) ; - parent -= GetParent()->GetClientAreaOrigin() ; - OffsetRgn( updateOuter , -parent.x , -parent.y ) ; - CopyRgn( updateOuter , updateTotal ) ; - - GetParent()->m_peer->SetNeedsDisplay( true , updateTotal ) ; - DisposeRgn(updateOuter) ; - DisposeRgn(updateInner) ; - DisposeRgn(updateTotal) ; - } - } -#endif - -#if 0 - Rect r = wxMacGetBoundsForControl(this , wxPoint( actualX,actualY), wxSize( actualWidth, actualHeight ) , false ) ; - - int outerBorder = MacGetLeftBorderSize() ; - if ( m_peer->NeedsFocusRect() && m_peer->HasFocus() ) - outerBorder += 4 ; - - if ( vis && ( outerBorder > 0 ) ) - { - // as the borders are drawn on the parent we have to properly invalidate all these areas - RgnHandle updateInner = NewRgn() , updateOuter = NewRgn() , updateTotal = NewRgn() ; + // now we know that we have something to do at all - Rect rect ; + // as the borders are drawn on the parent we have to properly invalidate all these areas + RgnHandle updateInner , updateOuter; + Rect rect ; - m_peer->GetRect( &rect ) ; - RectRgn( updateInner , &rect ) ; - InsetRect( &rect , -outerBorder , -outerBorder ) ; - RectRgn( updateOuter , &rect ) ; - DiffRgn( updateOuter , updateInner ,updateOuter ) ; + // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon + updateInner = NewRgn() ; + updateOuter = NewRgn() ; - /* - wxPoint parent(0, 0); -#if TARGET_API_MAC_OSX - // no offsetting needed when compositing -#else - GetParent()->MacWindowToRootWindow( &parent.x , &parent.y ) ; - parent -= GetParent()->GetClientAreaOrigin() ; - OffsetRgn( updateOuter , -parent.x , -parent.y ) ; -#endif - */ - CopyRgn( updateOuter , updateTotal ) ; - - rect = r ; - RectRgn( updateInner , &rect ) ; - InsetRect( &rect , -outerBorder , -outerBorder ) ; - RectRgn( updateOuter , &rect ) ; - DiffRgn( updateOuter , updateInner , updateOuter ) ; -/* - OffsetRgn( updateOuter , -parent.x , -parent.y ) ; -*/ - UnionRgn( updateOuter , updateTotal , updateTotal ) ; + m_peer->GetRect( &rect ) ; + RectRgn( updateInner, &rect ) ; + InsetRect( &rect , -outerBorder , -outerBorder ) ; + RectRgn( updateOuter, &rect ) ; + DiffRgn( updateOuter, updateInner , updateOuter ) ; - GetParent()->m_peer->SetNeedsDisplay( updateTotal ) ; - DisposeRgn(updateOuter) ; - DisposeRgn(updateInner) ; - DisposeRgn(updateTotal) ; - } -#endif + GetParent()->m_peer->SetNeedsDisplay( updateOuter ) ; + + DisposeRgn( updateOuter ) ; + DisposeRgn( updateInner ) ; } void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) @@ -1874,12 +1758,15 @@ void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags) return; } - if ( x == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) - x = currentX; - if ( y == wxDefaultCoord && !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) - y = currentY; + if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) + { + if ( x == wxDefaultCoord ) + x = currentX; + if ( y == wxDefaultCoord ) + y = currentY; + } - AdjustForParentClientOrigin(x, y, sizeFlags); + AdjustForParentClientOrigin( x, y, sizeFlags ); wxSize size = wxDefaultSize; if ( width == wxDefaultCoord ) @@ -1913,7 +1800,7 @@ void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags) } } - DoMoveWindow(x, y, width, height); + DoMoveWindow( x, y, width, height ); } wxPoint wxWindowMac::GetClientAreaOrigin() const @@ -1937,7 +1824,7 @@ wxPoint wxWindowMac::GetClientAreaOrigin() const void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight) { - if ( clientheight != wxDefaultCoord || clientheight != wxDefaultCoord ) + if ( clientwidth != wxDefaultCoord || clientheight != wxDefaultCoord ) { int currentclientwidth , currentclientheight ; int currentwidth , currentheight ; @@ -1952,12 +1839,14 @@ void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight) void wxWindowMac::SetLabel(const wxString& title) { - m_label = wxStripMenuCodes(title) ; + m_label = title ; if ( m_peer && m_peer->Ok() ) - m_peer->SetLabel( m_label ) ; + m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; - Refresh() ; + // do not trigger refreshes upon invisible and possible partly created objects + if ( MacIsReallyShown() ) + Refresh() ; } wxString wxWindowMac::GetLabel() const @@ -1967,98 +1856,18 @@ wxString wxWindowMac::GetLabel() const bool wxWindowMac::Show(bool show) { - bool former = MacIsReallyShown() ; if ( !wxWindowBase::Show(show) ) return false; - // TODO use visibilityChanged Carbon Event for OSX if ( m_peer ) m_peer->SetVisibility( show , true ) ; - if ( former != MacIsReallyShown() ) - MacPropagateVisibilityChanged() ; - -#if 1 - // patch from Sailesh Agrawal - wxShowEvent eventShow(GetId(), show); - eventShow.SetEventObject(this); - GetEventHandler()->ProcessEvent(eventShow); -#endif - return true; } -bool wxWindowMac::Enable(bool enable) +void wxWindowMac::DoEnable(bool enable) { - wxASSERT( m_peer->Ok() ) ; - bool former = MacIsReallyEnabled() ; - if ( !wxWindowBase::Enable(enable) ) - return false; - m_peer->Enable( enable ) ; - - if ( former != MacIsReallyEnabled() ) - MacPropagateEnabledStateChanged() ; - - return true; -} - -// -// status change propagations (will be not necessary for OSX later ) -// - -void wxWindowMac::MacPropagateVisibilityChanged() -{ -#if !TARGET_API_MAC_OSX - MacVisibilityChanged() ; - - wxWindowMac *child; - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) - { - child = node->GetData(); - if ( child->IsShown() ) - child->MacPropagateVisibilityChanged() ; - - node = node->GetNext(); - } -#endif -} - -void wxWindowMac::MacPropagateEnabledStateChanged() -{ -#if !TARGET_API_MAC_OSX - MacEnabledStateChanged() ; - - wxWindowMac *child; - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) - { - child = node->GetData(); - if ( child->IsEnabled() ) - child->MacPropagateEnabledStateChanged() ; - - node = node->GetNext(); - } -#endif -} - -void wxWindowMac::MacPropagateHiliteChanged() -{ -#if !TARGET_API_MAC_OSX - MacHiliteChanged() ; - - wxWindowMac *child; - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) - { - child = node->GetData(); - if (child /* && child->IsEnabled() */) - child->MacPropagateHiliteChanged() ; - - node = node->GetNext(); - } -#endif } // @@ -2075,6 +1884,7 @@ void wxWindowMac::MacHiliteChanged() void wxWindowMac::MacEnabledStateChanged() { + OnEnabled( m_peer->IsEnabled() ); } // @@ -2145,7 +1955,7 @@ void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, fontToUse = &m_font; wxClientDC dc( (wxWindowMac*) this ) ; - long lx,ly,ld,le ; + wxCoord lx,ly,ld,le ; dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ; if ( externalLeading ) *externalLeading = le ; @@ -2162,7 +1972,7 @@ void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, * we always intersect with the entire window, not only with the client area */ -void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect) +void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect) { if ( m_peer == NULL ) return ; @@ -2210,6 +2020,11 @@ void wxWindowMac::Thaw() #endif } +bool wxWindowMac::IsFrozen() const +{ + return m_frozenness != 0; +} + wxWindowMac *wxGetActiveWindow() { // actually this is a windows-only concept @@ -2217,7 +2032,7 @@ wxWindowMac *wxGetActiveWindow() } // Coordinates relative to the window -void wxWindowMac::WarpPointer(int x_pos, int y_pos) +void wxWindowMac::WarpPointer(int WXUNUSED(x_pos), int WXUNUSED(y_pos)) { // We really don't move the mouse programmatically under Mac. } @@ -2228,7 +2043,7 @@ void wxWindowMac::OnEraseBackground(wxEraseEvent& event) return ; #if TARGET_API_MAC_OSX - if ( MacGetTopLevelWindow()->MacUsesCompositing() && (!m_macBackgroundBrush.Ok() || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT ) ) + if ( !m_backgroundColour.Ok() || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) { event.Skip() ; } @@ -2294,7 +2109,7 @@ int wxWindowMac::GetScrollThumb(int orient) const return 0; } -void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh) +void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) { if ( orient == wxHORIZONTAL ) { @@ -2308,32 +2123,82 @@ void wxWindowMac::SetScrollPos(int orient, int pos, bool refresh) } } +void +wxWindowMac::AlwaysShowScrollbars(bool hflag, bool vflag) +{ + bool needVisibilityUpdate = false; + + if ( m_hScrollBarAlwaysShown != hflag ) + { + m_hScrollBarAlwaysShown = hflag; + needVisibilityUpdate = true; + } + + if ( m_vScrollBarAlwaysShown != vflag ) + { + m_vScrollBarAlwaysShown = vflag; + needVisibilityUpdate = true; + } + + if ( needVisibilityUpdate ) + DoUpdateScrollbarVisibility(); +} + // // we draw borders and grow boxes, are already set up and clipped in the current port / cgContextRef // our own window origin is at leftOrigin/rightOrigin // -void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin ) +void wxWindowMac::MacPaintGrowBox() +{ + if ( IsTopLevel() ) + return ; + + if ( MacHasScrollBarCorner() ) + { + Rect rect ; + + CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ; + wxASSERT( cgContext ) ; + + m_peer->GetRect( &rect ) ; + + int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; + CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ; + CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ; + CGContextSaveGState( cgContext ); + + if ( m_backgroundColour.Ok() ) + { + CGContextSetFillColorWithColor( cgContext, m_backgroundColour.GetCGColor() ); + } + else + { + CGContextSetRGBFillColor( cgContext, 1.0, 1.0 , 1.0 , 1.0 ); + } + CGContextFillRect( cgContext, cgrect ); + CGContextRestoreGState( cgContext ); + } +} + +void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(rightOrigin) ) { if ( IsTopLevel() ) return ; Rect rect ; bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ; - bool hasBothScrollbars = (m_hScrollBar && m_hScrollBar->IsShown()) && (m_vScrollBar && m_vScrollBar->IsShown()) ; - m_peer->GetRect( &rect ) ; // back to the surrounding frame rectangle + m_peer->GetRect( &rect ) ; InsetRect( &rect, -1 , -1 ) ; -#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 - if ( UMAGetSystemVersion() >= 0x1030 ) { CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left , rect.bottom - rect.top ) ; HIThemeFrameDrawInfo info ; - memset( &info, 0 , sizeof( info ) ) ; + memset( &info, 0 , sizeof(info) ) ; info.version = 0 ; info.kind = 0 ; @@ -2357,11 +2222,12 @@ void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin ) { HIThemeDrawFocusRect( &cgrect , true , cgContext , kHIThemeOrientationNormal ) ; } - +#if 0 // TODO REMOVE now done in a separate call earlier in drawing the window itself m_peer->GetRect( &rect ) ; - if ( hasBothScrollbars ) + if ( MacHasScrollBarCorner() ) { - int size = m_hScrollBar->GetWindowVariant() == wxWINDOW_VARIANT_NORMAL ? 16 : 12 ; + int variant = (m_hScrollBar == NULL ? m_vScrollBar : m_hScrollBar ) ->GetWindowVariant(); + int size = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; CGRect cgrect = CGRectMake( rect.right - size , rect.bottom - size , size , size ) ; CGPoint cgpoint = CGPointMake( rect.right - size , rect.bottom - size ) ; HIThemeGrowBoxDrawInfo info ; @@ -2369,35 +2235,12 @@ void wxWindowMac::MacPaintBorders( int leftOrigin , int rightOrigin ) info.version = 0 ; info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; info.kind = kHIThemeGrowBoxKindNone ; + // contrary to the docs ...SizeSmall does not work info.size = kHIThemeGrowBoxSizeNormal ; - info.direction = kThemeGrowRight | kThemeGrowDown ; + info.direction = 0 ; HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ; } - } - else #endif - { - wxTopLevelWindowMac* top = MacGetTopLevelWindow(); - if ( top ) - { - wxPoint pt(0, 0) ; - wxMacControl::Convert( &pt , GetParent()->m_peer , top->m_peer ) ; - OffsetRect( &rect , pt.x , pt.y ) ; - } - - if ( HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) ) - DrawThemeEditTextFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ; - else if ( HasFlag(wxSIMPLE_BORDER) ) - DrawThemeListBoxFrame( &rect, IsEnabled() ? kThemeStateActive : kThemeStateInactive ) ; - - if ( hasFocus ) - DrawThemeFocusRect( &rect , true ) ; - - if ( hasBothScrollbars ) - { - // GetThemeStandaloneGrowBoxBounds - // DrawThemeStandaloneNoGrowBox - } } } @@ -2411,48 +2254,51 @@ void wxWindowMac::RemoveChild( wxWindowBase *child ) wxWindowBase::RemoveChild( child ) ; } -// New function that will replace some of the above. -void wxWindowMac::SetScrollbar(int orient, int pos, int thumbVisible, - int range, bool refresh) +void wxWindowMac::DoUpdateScrollbarVisibility() { - if ( orient == wxHORIZONTAL ) + bool triggerSizeEvent = false; + + if ( m_hScrollBar ) { - if ( m_hScrollBar ) - { - if ( range == 0 || thumbVisible >= range ) - { - if ( m_hScrollBar->IsShown() ) - m_hScrollBar->Show(false) ; - } - else - { - if ( !m_hScrollBar->IsShown() ) - m_hScrollBar->Show(true) ; - } + bool showHScrollBar = m_hScrollBarAlwaysShown || m_hScrollBar->IsNeeded(); - m_hScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ; + if ( m_hScrollBar->IsShown() != showHScrollBar ) + { + m_hScrollBar->Show( showHScrollBar ); + triggerSizeEvent = true; } } - else + + if ( m_vScrollBar) { - if ( m_vScrollBar ) - { - if ( range == 0 || thumbVisible >= range ) - { - if ( m_vScrollBar->IsShown() ) - m_vScrollBar->Show(false) ; - } - else - { - if ( !m_vScrollBar->IsShown() ) - m_vScrollBar->Show(true) ; - } + bool showVScrollBar = m_vScrollBarAlwaysShown || m_vScrollBar->IsNeeded(); - m_vScrollBar->SetScrollbar( pos , thumbVisible , range , thumbVisible , refresh ) ; + if ( m_vScrollBar->IsShown() != showVScrollBar ) + { + m_vScrollBar->Show( showVScrollBar ) ; + triggerSizeEvent = true; } } MacRepositionScrollBars() ; + if ( triggerSizeEvent ) + { + wxSizeEvent event(GetSize(), m_windowId); + event.SetEventObject(this); + GetEventHandler()->ProcessEvent(event); + } +} + +// New function that will replace some of the above. +void wxWindowMac::SetScrollbar(int orient, int pos, int thumb, + int range, bool refresh) +{ + if ( orient == wxHORIZONTAL && m_hScrollBar ) + m_hScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh); + else if ( orient == wxVERTICAL && m_vScrollBar ) + m_vScrollBar->SetScrollbar(pos, thumb, range, thumb, refresh); + + DoUpdateScrollbarVisibility(); } // Does a physical scroll @@ -2464,32 +2310,25 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) int width , height ; GetClientSize( &width , &height ) ; -#if TARGET_API_MAC_OSX - if ( true /* 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 + // TODO: write optimal workaround wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ; if ( rect ) scrollrect.Intersect( *rect ) ; if ( m_peer->GetNeedsDisplay() ) { - // becuase HIViewScrollRect does not scroll the already invalidated area we have two options + // because HIViewScrollRect does not scroll the already invalidated area we have two options: + // in case there is already a pending redraw on that area // either immediate redraw or full invalidate #if 1 // 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() ; + HIViewRender(m_peer->GetControlRef()) ; #endif } @@ -2497,77 +2336,11 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ; 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() ; + HIViewRender(m_peer->GetControlRef()) ; #endif } - else -#endif - { - wxPoint pos; - pos.x = - pos.y = 0; - - Rect scrollrect; - RgnHandle updateRgn = NewRgn() ; - - { - wxClientDC dc(this) ; - wxMacPortSetter helper(&dc) ; - - m_peer->GetRectInWindowCoords( &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 ) ; - - // now scroll the former update region as well and add the new update region - 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 ) ; - } - - InvalWindowRgn(rootWindow, updateRgn ) ; - DisposeRgn( updateRgn ) ; - DisposeRgn( formerUpdateRgn ) ; - DisposeRgn( scrollRgn ) ; - } - - Update() ; - } wxWindowMac *child; int x, y, w, h; @@ -2589,11 +2362,11 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) { wxRect rc( x, y, w, h ); if (rect->Intersects( rc )) - child->SetSize( x + dx, y + dy, w, h ); + child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE ); } else { - child->SetSize( x + dx, y + dy, w, h ); + child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE ); } } } @@ -2649,28 +2422,14 @@ void wxWindowMac::OnSetFocus( wxFocusEvent& event ) //wxChildFocusEvent eventFocus(this); //(void)GetEventHandler()->ProcessEvent(eventFocus); -#if !wxMAC_USE_CORE_GRAPHICS - bool bIsFocusEvent = (event.GetEventType() == wxEVT_SET_FOCUS); -#endif - - // enable for patch 1376506 - perhaps? -#if 0 - if ( bIsFocusEvent ) - SetUserFocusWindow( GetControlOwner( GetPeer()->GetControlRef() ) ); - else - SetUserFocusWindow( kUserFocusAuto ); -#endif - if ( MacGetTopLevelWindow() && m_peer->NeedsFocusRect() ) { -#if wxMAC_USE_CORE_GRAPHICS GetParent()->Refresh() ; -#else wxMacWindowStateSaver sv( this ) ; Rect rect ; m_peer->GetRect( &rect ) ; - // auf den umgebenden Rahmen zurŸck + // auf den umgebenden Rahmen zurチᅡ゚ck InsetRect( &rect, -1 , -1 ) ; wxTopLevelWindowMac* top = MacGetTopLevelWindow(); @@ -2684,6 +2443,7 @@ void wxWindowMac::OnSetFocus( wxFocusEvent& event ) rect.bottom += pt.y ; } + bool bIsFocusEvent = (event.GetEventType() == wxEVT_SET_FOCUS); DrawThemeFocusRect( &rect , bIsFocusEvent ) ; if ( !bIsFocusEvent ) { @@ -2692,7 +2452,6 @@ void wxWindowMac::OnSetFocus( wxFocusEvent& event ) // we have to invalidate things, we cannot simple redraw MacInvalidateBorders() ; } -#endif } event.Skip(); @@ -2702,7 +2461,7 @@ void wxWindowMac::OnInternalIdle() { // This calls the UI-update mechanism (querying windows for // menu/toolbar/control state information) - if (wxUpdateUIEvent::CanUpdate(this)) + if (wxUpdateUIEvent::CanUpdate(this) && IsShown()) UpdateWindowUI(wxUPDATE_UI_FROMIDLE); } @@ -2756,7 +2515,7 @@ bool wxWindowMac::MacSetupCursor( const wxPoint& pt ) return cursor.Ok() ; } -wxString wxWindowMac::MacGetToolTipString( wxPoint &pt ) +wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) ) { #if wxUSE_TOOLTIPS if ( m_tooltip ) @@ -2774,11 +2533,9 @@ void wxWindowMac::ClearBackground() void wxWindowMac::Update() { -#if TARGET_API_MAC_OSX - MacGetTopLevelWindow()->MacPerformUpdates() ; -#else - ::Draw1Control( m_peer->GetControlRef() ) ; -#endif + wxTopLevelWindowMac* top = MacGetTopLevelWindow(); + if (top) + top->MacPerformUpdates() ; } wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const @@ -2920,7 +2677,7 @@ void wxWindowMac::MacUpdateClippedRects() const /* This function must not change the updatergn ! */ -bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) +bool wxWindowMac::MacDoRedraw( void* updatergnr , long time ) { bool handled = false ; Rect updatebounds ; @@ -2945,9 +2702,9 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) // the grow-box area of a scrolled window (scroll sample) wxDC* dc = new wxWindowDC(this); if ( IsTopLevel() ) - dc->SetClippingRegion(wxRegion(updatergn)); + dc->SetClippingRegion(wxRegion(HIShapeCreateWithQDRgn(updatergn))); else - dc->SetClippingRegion(wxRegion(newupdate)); + dc->SetClippingRegion(wxRegion(HIShapeCreateWithQDRgn(newupdate))); wxEraseEvent eevent( GetId(), dc ); eevent.SetEventObject( this ); @@ -2955,9 +2712,11 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) delete dc ; } + MacPaintGrowBox(); + // calculate a client-origin version of the update rgn and set m_updateRegion to that OffsetRgn( newupdate , -origin.x , -origin.y ) ; - m_updateRegion = newupdate ; + m_updateRegion = wxRegion(HIShapeCreateWithQDRgn(newupdate)) ; DisposeRgn( newupdate ) ; if ( !m_updateRegion.Empty() ) @@ -3008,19 +2767,7 @@ bool wxWindowMac::MacDoRedraw( WXHRGN updatergnr , long time ) eventNc.SetEventObject( child ); if ( !child->GetEventHandler()->ProcessEvent( eventNc ) ) { -#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 - if ( UMAGetSystemVersion() >= 0x1030 ) - { - child->MacPaintBorders(0, 0) ; - } - else -#endif - { - wxWindowDC dc(this) ; - dc.SetClippingRegion(wxRegion(updatergn)); - wxMacPortSetter helper(&dc) ; - child->MacPaintBorders(0, 0) ; - } + child->MacPaintBorders(0, 0) ; } } } @@ -3037,45 +2784,119 @@ WXWindow wxWindowMac::MacGetTopLevelWindowRef() const while ( iter ) { if ( iter->IsTopLevel() ) - return ((wxTopLevelWindow*)iter)->MacGetWindowRef() ; - + { + wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow); + if ( toplevel ) + return toplevel->MacGetWindowRef(); +#if wxUSE_POPUPWIN + wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow); + if ( popupwin ) + return popupwin->MacGetPopupWindowRef(); +#endif + } iter = iter->GetParent() ; } - wxASSERT_MSG( 1 , wxT("No valid mac root window") ) ; - return NULL ; } +bool wxWindowMac::MacHasScrollBarCorner() const +{ + /* Returns whether the scroll bars in a wxScrolledWindow should be + * shortened. Scroll bars should be shortened if either: + * + * - both scroll bars are visible, or + * + * - there is a resize box in the parent frame's corner and this + * window shares the bottom and right edge with the parent + * frame. + */ + + if ( m_hScrollBar == NULL && m_vScrollBar == NULL ) + return false; + + if ( ( m_hScrollBar && m_hScrollBar->IsShown() ) + && ( m_vScrollBar && m_vScrollBar->IsShown() ) ) + { + // Both scroll bars visible + return true; + } + else + { + wxPoint thisWindowBottomRight = GetScreenRect().GetBottomRight(); + + for ( const wxWindow *win = this; win; win = win->GetParent() ) + { + const wxFrame *frame = wxDynamicCast( win, wxFrame ) ; + if ( frame ) + { + if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER ) + { + // Parent frame has resize handle + wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight(); + + // Note: allow for some wiggle room here as wxMac's + // window rect calculations seem to be imprecise + if ( abs( thisWindowBottomRight.x - frameBottomRight.x ) <= 2 + && abs( thisWindowBottomRight.y - frameBottomRight.y ) <= 2 ) + { + // Parent frame has resize handle and shares + // right bottom corner + return true ; + } + else + { + // Parent frame has resize handle but doesn't + // share right bottom corner + return false ; + } + } + else + { + // Parent frame doesn't have resize handle + return false ; + } + } + } + + // No parent frame found + return false ; + } +} + void wxWindowMac::MacCreateScrollBars( long style ) { wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ; if ( style & ( wxVSCROLL | wxHSCROLL ) ) { - bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ; int scrlsize = MAC_SCROLLBAR_SIZE ; - wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL ; if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI ) { scrlsize = MAC_SMALL_SCROLLBAR_SIZE ; - variant = wxWINDOW_VARIANT_SMALL ; } - int adjust = hasBoth ? scrlsize - 1: 0 ; + int adjust = MacHasScrollBarCorner() ? scrlsize - 1: 0 ; int width, height ; GetClientSize( &width , &height ) ; wxPoint vPoint(width - scrlsize, 0) ; wxSize vSize(scrlsize, height - adjust) ; - wxPoint hPoint(0 , height - scrlsize ) ; - wxSize hSize( width - adjust, scrlsize) ; + wxPoint hPoint(0, height - scrlsize) ; + wxSize hSize(width - adjust, scrlsize) ; + // we have to set the min size to a smaller value, otherwise they cannot get smaller (InitialSize sets MinSize) if ( style & wxVSCROLL ) - m_vScrollBar = new wxScrollBar(this, wxID_ANY, vPoint, vSize , wxVERTICAL); + { + m_vScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL); + m_vScrollBar->SetMinSize( wxDefaultSize ); + } if ( style & wxHSCROLL ) - m_hScrollBar = new wxScrollBar(this, wxID_ANY, hPoint, hSize , wxHORIZONTAL); + { + m_hScrollBar = new wxScrollBar((wxWindow*)this, wxID_ANY, hPoint, hSize , wxHORIZONTAL); + m_hScrollBar->SetMinSize( wxDefaultSize ); + } } // because the create does not take into account the client area origin @@ -3085,10 +2906,9 @@ void wxWindowMac::MacCreateScrollBars( long style ) bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const { - if ( child != NULL && ( child == m_hScrollBar || child == m_vScrollBar ) ) - return false ; - else - return true ; + bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar))); + + return result ; } void wxWindowMac::MacRepositionScrollBars() @@ -3096,9 +2916,8 @@ void wxWindowMac::MacRepositionScrollBars() if ( !m_hScrollBar && !m_vScrollBar ) return ; - bool hasBoth = (m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ; int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; - int adjust = hasBoth ? scrlsize - 1 : 0 ; + int adjust = MacHasScrollBarCorner() ? scrlsize - 1 : 0 ; // get real client area int width, height ; @@ -3208,13 +3027,15 @@ long wxWindowMac::MacGetLeftBorderSize() const if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER)) { + // this metric is only the 'outset' outside the simple frame rect GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ; - border += 1 ; // the metric above is only the 'outset' outside the simple frame rect + border += 1 ; } else if (HasFlag(wxSIMPLE_BORDER)) { + // this metric is only the 'outset' outside the simple frame rect GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; - border += 1 ; // the metric above is only the 'outset' outside the simple frame rect + border += 1 ; } return border ; @@ -3288,15 +3109,18 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) } } -void wxWindowMac::OnPaint( wxPaintEvent & event ) +void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) ) { - if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL ) + if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL + && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT ) CallNextEventHandler( (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , (EventRef) wxTheApp->MacGetCurrentEvent() ) ; } -void wxWindowMac::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) ) +void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control), + wxInt16 WXUNUSED(controlpart), + bool WXUNUSED(mouseStillDown)) { } @@ -3304,8 +3128,8 @@ Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxS { int x, y, w, h ; - window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin) ; - Rect bounds = { y, x, y + h, x + w }; + window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ; + Rect bounds = { y, x, y + h, x + w }; return bounds ; } @@ -3318,7 +3142,6 @@ wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENT bool wxWindowMac::Reparent(wxWindowBase *newParentBase) { wxWindowMac *newParent = (wxWindowMac *)newParentBase; - if ( !wxWindowBase::Reparent(newParent) ) return false; @@ -3331,3 +3154,26 @@ bool wxWindowMac::Reparent(wxWindowBase *newParentBase) return true; } + +bool wxWindowMac::SetTransparent(wxByte alpha) +{ + SetBackgroundStyle(wxBG_STYLE_TRANSPARENT); + + if ( alpha != m_macAlpha ) + { + m_macAlpha = alpha ; + Refresh() ; + } + return true ; +} + + +bool wxWindowMac::CanSetTransparent() +{ + return true ; +} + +wxByte wxWindowMac::GetTransparent() const +{ + return m_macAlpha ; +}