X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b175b96ba0ce7b657991465ce5cd2ca53e7ab7bc..70aaa701b47c37505a1821b91a4f8543312923b0:/src/mac/carbon/window.cpp diff --git a/src/mac/carbon/window.cpp b/src/mac/carbon/window.cpp index 1f199792dc..9d20d9a04c 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 @@ -66,7 +69,6 @@ #include extern wxList wxPendingDelete; -wxWindowMac* gFocusWindow = NULL ; #ifdef __WXUNIVERSAL__ IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase) @@ -83,6 +85,7 @@ BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase) EVT_SYS_COLOUR_CHANGED(wxWindowMac::OnSysColourChanged) EVT_INIT_DIALOG(wxWindowMac::OnInitDialog) EVT_SET_FOCUS(wxWindowMac::OnSetFocus) + EVT_KILL_FOCUS(wxWindowMac::OnSetFocus) EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent) END_EVENT_TABLE() @@ -93,7 +96,7 @@ END_EVENT_TABLE() #define wxMAC_DEBUG_REDRAW 0 #endif -#define wxMAC_USE_THEME_BORDER 0 +#define wxMAC_USE_THEME_BORDER 1 // --------------------------------------------------------------------------- // Carbon Events @@ -102,25 +105,32 @@ END_EVENT_TABLE() extern long wxMacTranslateKey(unsigned char key, unsigned char code) ; pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessage , SInt16 iDepth , Boolean iIsColor ) ; -#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3 +#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[] = { + { kEventClassControl , kEventControlHit } , #if TARGET_API_MAC_OSX { kEventClassControl , kEventControlDraw } , { kEventClassControl , kEventControlVisibilityChanged } , { kEventClassControl , kEventControlEnabledStateChanged } , { kEventClassControl , kEventControlHiliteChanged } , -// { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only + { kEventClassControl , kEventControlSetFocusPart } , + + { kEventClassService , kEventServiceGetTypes }, + { kEventClassService , kEventServiceCopy }, + { kEventClassService , kEventServicePaste }, + + // { kEventClassControl , kEventControlInvalidateForSizeChange } , // 10.3 only // { kEventClassControl , kEventControlBoundsChanged } , - - {} -#else - {} #endif } ; @@ -137,6 +147,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl switch( GetEventKind( event ) ) { +#if TARGET_API_MAC_OSX case kEventControlDraw : { RgnHandle updateRgn = NULL ; @@ -184,12 +195,136 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl case kEventControlHiliteChanged : thisWindow->MacHiliteChanged() ; break ; + case kEventControlSetFocusPart : + { + Boolean focusEverything = false ; + ControlPartCode controlPart = cEvent.GetParameter(kEventParamControlPart , typeControlPartCode ); + if ( cEvent.GetParameter(kEventParamControlFocusEverything , &focusEverything ) == noErr ) + { + } + if ( controlPart == kControlFocusNoPart ) + { + #if wxUSE_CARET + if ( thisWindow->GetCaret() ) + { + thisWindow->GetCaret()->OnKillFocus(); + } + #endif // wxUSE_CARET + wxFocusEvent event( wxEVT_KILL_FOCUS, thisWindow->GetId()); + event.SetEventObject(thisWindow); + thisWindow->GetEventHandler()->ProcessEvent(event) ; + } + else + { + // panel wants to track the window which was the last to have focus in it + wxChildFocusEvent eventFocus(thisWindow); + thisWindow->GetEventHandler()->ProcessEvent(eventFocus); + + #if wxUSE_CARET + if ( thisWindow->GetCaret() ) + { + thisWindow->GetCaret()->OnSetFocus(); + } + #endif // wxUSE_CARET + + wxFocusEvent event(wxEVT_SET_FOCUS, thisWindow->GetId()); + event.SetEventObject(thisWindow); + thisWindow->GetEventHandler()->ProcessEvent(event) ; + } + if ( thisWindow->MacIsUserPane() ) + result = noErr ; + } + break ; +#endif + case kEventControlHit : + { + result = thisWindow->MacControlHit( handler , event ) ; + } + break ; default : break ; } 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 ; @@ -199,6 +334,8 @@ pascal OSStatus wxMacWindowEventHandler( EventHandlerCallRef handler , EventRef case kEventClassControl : result = wxMacWindowControlEventHandler( handler, event, data ) ; break ; + case kEventClassService : + result = wxMacWindowServiceEventHandler( handler, event , data ) ; default : break ; } @@ -368,14 +505,10 @@ pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessa wxWindow* wx = (wxWindow*) wxFindControlFromMacControl( iControl ) ; if ( wx != NULL ) { - /* const wxBrush &brush = wx->MacGetBackgroundBrush() ; if ( brush.Ok() ) { - wxDC::MacSetupBackgroundForCurrentPort( brush ) ; - */ - // this clipping is only needed for non HIView RgnHandle clip = NewRgn() ; int x = 0 , y = 0; @@ -387,7 +520,6 @@ pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessa DisposeRgn( clip ) ; status = noErr ; - /* } else if ( wx->MacIsUserPane() ) { @@ -395,7 +527,6 @@ pascal OSStatus wxMacSetupControlBackground( ControlRef iControl , SInt16 iMessa // setup of our parent ourselves status = SetUpControlBackground( (ControlRef) wx->GetParent()->GetHandle() , iDepth , iIsColor ) ; } - */ } } break ; @@ -423,10 +554,29 @@ 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; +#endif // as all windows are created with WS_VISIBLE style... m_isShown = TRUE; @@ -435,8 +585,6 @@ void wxWindowMac::Init() m_vScrollBar = NULL ; m_macBackgroundBrush = wxNullBrush ; - m_macControl = NULL ; - m_macIsUserPane = TRUE; // make sure all proc ptrs are available @@ -498,13 +646,13 @@ 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 ; + // we currently are not using this hook + // ::SetControlColorProc( *m_peer , NULL ) ; + m_peer->Dispose() ; } if ( g_MacLastWindow == this ) @@ -519,11 +667,6 @@ wxWindowMac::~wxWindowMac() frame->SetLastFocus( NULL ) ; } - if ( gFocusWindow == this ) - { - gFocusWindow = NULL ; - } - DestroyChildren(); // delete our drop target if we've got one @@ -534,14 +677,19 @@ wxWindowMac::~wxWindowMac() m_dropTarget = NULL; } #endif // wxUSE_DRAG_AND_DROP + delete m_peer ; +} + +WXWidget wxWindowMac::GetHandle() const +{ + return (WXWidget) m_peer->GetControlRef() ; } -// -void wxWindowMac::MacInstallEventHandler() +void wxWindowMac::MacInstallEventHandler( WXWidget control ) { - wxAssociateControlWithMacControl( (ControlRef) m_macControl , this ) ; - InstallControlEventHandler( (ControlRef) m_macControl, GetwxMacWindowEventHandlerUPP(), + wxAssociateControlWithMacControl( (ControlRef) control , this ) ; + InstallControlEventHandler( (ControlRef) control , GetwxMacWindowEventHandlerUPP(), GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_macControlEventHandler); @@ -567,29 +715,31 @@ 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->GetControlRefAddr() ); + MacPostControlCreate(pos,size) ; #if !TARGET_API_MAC_OSX - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneDrawProcTag, - sizeof(gControlUserPaneDrawUPP),(Ptr) &gControlUserPaneDrawUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneHitTestProcTag, - sizeof(gControlUserPaneHitTestUPP),(Ptr) &gControlUserPaneHitTestUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneTrackingProcTag, - sizeof(gControlUserPaneTrackingUPP),(Ptr) &gControlUserPaneTrackingUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneIdleProcTag, - sizeof(gControlUserPaneIdleUPP),(Ptr) &gControlUserPaneIdleUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneKeyDownProcTag, - sizeof(gControlUserPaneKeyDownUPP),(Ptr) &gControlUserPaneKeyDownUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneActivateProcTag, - sizeof(gControlUserPaneActivateUPP),(Ptr) &gControlUserPaneActivateUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneFocusProcTag, - sizeof(gControlUserPaneFocusUPP),(Ptr) &gControlUserPaneFocusUPP); - SetControlData((ControlRef) m_macControl,kControlEntireControl,kControlUserPaneBackgroundProcTag, - sizeof(gControlUserPaneBackgroundUPP),(Ptr) &gControlUserPaneBackgroundUPP); + m_peer->SetData(kControlEntireControl,kControlUserPaneDrawProcTag,&gControlUserPaneDrawUPP) ; + m_peer->SetData(kControlEntireControl,kControlUserPaneHitTestProcTag,&gControlUserPaneHitTestUPP) ; + m_peer->SetData(kControlEntireControl,kControlUserPaneTrackingProcTag,&gControlUserPaneTrackingUPP) ; + m_peer->SetData(kControlEntireControl,kControlUserPaneIdleProcTag,&gControlUserPaneIdleUPP) ; + m_peer->SetData(kControlEntireControl,kControlUserPaneKeyDownProcTag,&gControlUserPaneKeyDownUPP) ; + m_peer->SetData(kControlEntireControl,kControlUserPaneActivateProcTag,&gControlUserPaneActivateUPP) ; + m_peer->SetData(kControlEntireControl,kControlUserPaneFocusProcTag,&gControlUserPaneFocusUPP) ; + m_peer->SetData(kControlEntireControl,kControlUserPaneBackgroundProcTag,&gControlUserPaneBackgroundUPP) ; #endif } #ifndef __WXUNIVERSAL__ @@ -609,15 +759,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 ) ; + m_peer->SetReference( (long) this ) ; - MacInstallEventHandler(); + MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ); ControlRef container = (ControlRef) GetParent()->GetHandle() ; wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; - ::EmbedControl( (ControlRef) m_macControl , container ) ; + ::EmbedControl( m_peer->GetControlRef() , container ) ; // adjust font, controlsize etc DoSetWindowVariant( m_windowVariant ) ; @@ -625,38 +775,27 @@ 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->GetControlRef() , wxMacSetupControlBackgroundUPP ) ; #endif - - UMASetControlTitle( (ControlRef) m_macControl , wxStripMenuCodes(m_label) , m_font.GetEncoding() ) ; + m_peer->SetTitle( wxStripMenuCodes(m_label) ) ; - 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 ; @@ -697,7 +836,7 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) wxFAIL_MSG(_T("unexpected window variant")); break ; } - ::SetControlData( (ControlRef) m_macControl , kControlEntireControl, kControlSizeTag, sizeof( ControlSize ), &size ); + m_peer->SetData(kControlEntireControl, kControlSizeTag,&size ) ; wxFont font ; font.MacCreateThemeFont( themeFont ) ; @@ -706,38 +845,7 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) void wxWindowMac::MacUpdateControlFont() { - ControlFontStyleRec fontStyle; - if ( m_font.MacGetThemeFontID() != kThemeCurrentPortFont ) - { - switch( m_font.MacGetThemeFontID() ) - { - case kThemeSmallSystemFont : fontStyle.font = kControlFontSmallSystemFont ; break ; - case 109 /*mini font */ : fontStyle.font = -5 ; break ; - case kThemeSystemFont : fontStyle.font = kControlFontBigSystemFont ; break ; - default : fontStyle.font = kControlFontBigSystemFont ; break ; - } - fontStyle.flags = kControlUseFontMask ; - } - else - { - fontStyle.font = m_font.MacGetFontNum() ; - fontStyle.style = m_font.MacGetFontStyle() ; - fontStyle.size = m_font.MacGetFontSize() ; - fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask ; - } - - fontStyle.just = teJustLeft ; - fontStyle.flags |= kControlUseJustMask ; - if ( ( GetWindowStyle() & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL ) - fontStyle.just = teJustCenter ; - else if ( ( GetWindowStyle() & wxALIGN_MASK ) & wxALIGN_RIGHT ) - fontStyle.just = teJustRight ; - - - fontStyle.foreColor = MAC_WXCOLORREF(GetForegroundColour().GetPixel() ) ; - fontStyle.flags |= kControlUseForeColorMask ; - - ::SetControlFontStyle( (ControlRef) m_macControl , &fontStyle ); + m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; Refresh() ; } @@ -766,17 +874,18 @@ bool wxWindowMac::SetBackgroundColour(const wxColour& col ) return false ; wxBrush brush ; - if ( col == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) ) + wxColour newCol(GetBackgroundColour()); + if ( newCol == wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE) ) { brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ; } - else if ( col == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) ) + else if ( newCol == wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE ) ) { brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ; } else { - brush.SetColour( col ) ; + brush.SetColour( newCol ) ; } MacSetBackgroundBrush( brush ) ; @@ -788,73 +897,58 @@ bool wxWindowMac::SetBackgroundColour(const wxColour& col ) bool wxWindowMac::MacCanFocus() const { - wxASSERT( m_macControl != NULL ) ; - - return true ; + // 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 ) ; + return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ; } void wxWindowMac::SetFocus() { - if ( gFocusWindow == this ) - return ; - if ( AcceptsFocus() ) { - if (gFocusWindow ) - { -#if wxUSE_CARET - // Deal with caret - if ( gFocusWindow->m_caret ) - { - gFocusWindow->m_caret->OnKillFocus(); - } -#endif // wxUSE_CARET -#ifndef __WXUNIVERSAL__ - wxWindow* control = wxDynamicCast( gFocusWindow , wxWindow ) ; - // TODO we must use the built-in focusing - if ( control && control->GetHandle() /* && control->MacIsReallyShown() */ ) - { - UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetTopLevelWindowRef() , (ControlRef) control->GetHandle() , kControlFocusNoPart ) ; - control->MacRedrawControl() ; - } +#if !TARGET_API_MAC_OSX + wxWindow* former = FindFocus() ; #endif - // Without testing the window id, for some reason - // a kill focus event can still be sent to - // the control just being focussed. - int thisId = this->m_windowId; - int gFocusWindowId = gFocusWindow->m_windowId; - if (gFocusWindowId != thisId) - { - wxFocusEvent event(wxEVT_KILL_FOCUS, gFocusWindow->m_windowId); - event.SetEventObject(gFocusWindow); - gFocusWindow->GetEventHandler()->ProcessEvent(event) ; - } + OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ; + // as we cannot rely on the control features to find out whether we are in full keyboard mode, we can only + // leave in case of an error + if ( err == errCouldntSetFocus ) + return ; + +#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) ; } - gFocusWindow = this ; + // send new focus event { - #if wxUSE_CARET - // Deal with caret - if ( m_caret ) - { - m_caret->OnSetFocus(); - } - #endif // wxUSE_CARET - // panel wants to track the window which was the last to have focus in it - wxChildFocusEvent eventFocus(this); - GetEventHandler()->ProcessEvent(eventFocus); - - #ifndef __WXUNIVERSAL__ - wxControl* control = wxDynamicCast( gFocusWindow , wxControl ) ; - if ( control && control->GetHandle() ) - { - UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetTopLevelWindowRef() , (ControlRef) control->GetHandle() , kControlFocusNextPart ) ; - } - #endif - wxFocusEvent event(wxEVT_SET_FOCUS, m_windowId); - event.SetEventObject(this); - GetEventHandler()->ProcessEvent(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 } } @@ -901,7 +995,7 @@ void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y, int& w, int& h) const { Rect bounds ; - GetControlBounds( (ControlRef) m_macControl , &bounds ) ; + m_peer->GetRect( &bounds ) ; x = bounds.left ; @@ -913,11 +1007,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 ; } @@ -928,6 +1018,8 @@ bool wxWindowMac::MacGetBoundsForControl(const wxPoint& pos, int& x, int& y, int& w, int& h , bool adjustOrigin ) const { + // 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 @@ -936,6 +1028,12 @@ bool wxWindowMac::MacGetBoundsForControl(const wxPoint& pos, #if !TARGET_API_MAC_OSX GetParent()->MacWindowToRootWindow( &x , &y ) ; #endif + + x += MacGetLeftBorderSize() ; + y += MacGetTopBorderSize() ; + w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ; + h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ; + if ( adjustOrigin ) AdjustForParentClientOrigin( x , y ) ; return true ; @@ -944,18 +1042,22 @@ bool wxWindowMac::MacGetBoundsForControl(const wxPoint& pos, // Get total size void wxWindowMac::DoGetSize(int *x, int *y) const { -#if TARGET_API_MAC_OSX + // take the size of the control and add the borders that have to be drawn outside int x1 , y1 , w1 ,h1 ; +#if TARGET_API_MAC_OSX MacGetPositionAndSizeFromControl( x1 , y1, w1 ,h1 ) ; - if(x) *x = w1 ; - if(y) *y = h1 ; #else Rect bounds ; - GetControlBounds( (ControlRef) m_macControl , &bounds ) ; - if(x) *x = bounds.right - bounds.left ; - if(y) *y = bounds.bottom - bounds.top ; + m_peer->GetRect( &bounds ) ; + w1 = bounds.right - bounds.left ; + h1 = bounds.bottom - bounds.top ; #endif + w1 += MacGetLeftBorderSize() + MacGetRightBorderSize() ; + h1 += MacGetTopBorderSize() + MacGetBottomBorderSize() ; + + if(x) *x = w1 ; + if(y) *y = h1 ; } void wxWindowMac::DoGetPosition(int *x, int *y) const @@ -963,6 +1065,8 @@ void wxWindowMac::DoGetPosition(int *x, int *y) const #if TARGET_API_MAC_OSX int x1 , y1 , w1 ,h1 ; MacGetPositionAndSizeFromControl( x1 , y1, w1 ,h1 ) ; + x1 -= MacGetLeftBorderSize() ; + y1 -= MacGetTopBorderSize() ; if ( !IsTopLevel() ) { wxWindow *parent = GetParent(); @@ -977,11 +1081,13 @@ void wxWindowMac::DoGetPosition(int *x, int *y) const if(y) *y = y1 ; #else Rect bounds ; - GetControlBounds( (ControlRef) m_macControl , &bounds ) ; + m_peer->GetRect( &bounds ) ; wxCHECK_RET( GetParent() , wxT("Missing Parent") ) ; int xx = bounds.left ; int yy = bounds.top ; + xx -= MacGetLeftBorderSize() ; + yy -= MacGetTopBorderSize() ; if ( !GetParent()->IsTopLevel() ) { @@ -1012,8 +1118,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 ; @@ -1040,9 +1145,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 ; } @@ -1069,12 +1172,20 @@ void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const { #if TARGET_API_MAC_OSX - HIPoint pt ; + wxPoint pt ; if ( x ) pt.x = *x ; if ( y ) pt.y = *y ; if ( !IsTopLevel() ) - HIViewConvertPoint( &pt , (ControlRef) m_macControl , (ControlRef) MacGetTopLevelWindow()->GetHandle() ) ; + { + wxTopLevelWindowMac* top = MacGetTopLevelWindow(); + if (top) + { + pt.x -= MacGetLeftBorderSize() ; + pt.y -= MacGetTopBorderSize() ; + wxMacControl::Convert( &pt , m_peer , top->m_peer ) ; + } + } if ( x ) *x = (int) pt.x ; if ( y ) *y = (int) pt.y ; @@ -1082,7 +1193,7 @@ void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const if ( !IsTopLevel() ) { Rect bounds ; - GetControlBounds( (ControlRef) m_macControl , &bounds ) ; + m_peer->GetRect( &bounds ) ; if(x) *x += bounds.left ; if(y) *y += bounds.top ; } @@ -1102,12 +1213,16 @@ void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const { #if TARGET_API_MAC_OSX - HIPoint pt ; + wxPoint pt ; if ( x ) pt.x = *x ; if ( y ) pt.y = *y ; if ( !IsTopLevel() ) - HIViewConvertPoint( &pt , (ControlRef) MacGetTopLevelWindow()->GetHandle() , (ControlRef) m_macControl ) ; + { + wxMacControl::Convert( &pt , MacGetTopLevelWindow()->m_peer , m_peer ) ; + pt.x += MacGetLeftBorderSize() ; + pt.y += MacGetTopBorderSize() ; + } if ( x ) *x = (int) pt.x ; if ( y ) *y = (int) pt.y ; @@ -1115,7 +1230,7 @@ void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const if ( !IsTopLevel() ) { Rect bounds ; - GetControlBounds( (ControlRef) m_macControl , &bounds ) ; + m_peer->GetRect( &bounds ) ; if(x) *x -= bounds.left ; if(y) *y -= bounds.top ; } @@ -1136,17 +1251,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 ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) { GetRegionBounds( rgn , &content ) ; DisposeRgn( rgn ) ; } else { - GetControlBounds( (ControlRef) m_macControl , &content ) ; + m_peer->GetRect( &content ) ; } Rect structure ; - GetControlBounds( (ControlRef) m_macControl , &structure ) ; + m_peer->GetRect( &structure ) ; #if !TARGET_API_MAC_OSX OffsetRect( &content , -structure.left , -structure.top ) ; #endif @@ -1164,17 +1279,17 @@ wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const Rect content ; - if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr ) + if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) { GetRegionBounds( rgn , &content ) ; DisposeRgn( rgn ) ; } else { - GetControlBounds( (ControlRef) m_macControl , &content ) ; + m_peer->GetRect( &content ) ; } Rect structure ; - GetControlBounds( (ControlRef) m_macControl , &structure ) ; + m_peer->GetRect( &structure ) ; #if !TARGET_API_MAC_OSX OffsetRect( &content , -structure.left , -structure.top ) ; #endif @@ -1196,18 +1311,18 @@ void wxWindowMac::DoGetClientSize(int *x, int *y) const RgnHandle rgn = NewRgn() ; Rect content ; - if ( GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) == noErr ) + if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) { GetRegionBounds( rgn , &content ) ; DisposeRgn( rgn ) ; } else { - GetControlBounds( (ControlRef) m_macControl , &content ) ; + m_peer->GetRect( &content ) ; } #if !TARGET_API_MAC_OSX Rect structure ; - GetControlBounds( (ControlRef) m_macControl , &structure ) ; + m_peer->GetRect( &structure ) ; OffsetRect( &content , -structure.left , -structure.top ) ; #endif ww = content.right - content.left ; @@ -1281,27 +1396,30 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) wxASSERT_MSG( m_cursor.Ok(), wxT("cursor must be valid after call to the base version")); - - /* - - TODO why do we have to use current coordinates ? - Point pt ; - wxWindowMac *mouseWin ; - GetMouse( &pt ) ; - - // Change the cursor NOW if we're within the correct window - - if ( MacGetWindowFromPoint( wxPoint( pt.h , pt.v ) , &mouseWin ) ) + wxWindowMac *mouseWin = 0 ; { - if ( mouseWin == this && !wxIsBusy() ) - { - m_cursor.MacInstall() ; - } + WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; + 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( pt , window , &part ) ; + if ( control ) + mouseWin = wxFindControlFromMacControl( control ) ; + + if ( swapped ) + QDSwapPort( savePort , NULL ) ; } - */ - if ( !wxIsBusy() ) + + if ( mouseWin == this && !wxIsBusy() ) { m_cursor.MacInstall() ; } @@ -1314,7 +1432,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) ; @@ -1363,6 +1490,10 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) DoGetSize( &former_w , &former_h ) ; #else MacGetPositionAndSizeFromControl( former_x , former_y , former_w , former_h ) ; + former_x -= MacGetLeftBorderSize() ; + former_y -= MacGetTopBorderSize() ; + former_w += MacGetLeftBorderSize() + MacGetRightBorderSize() ; + former_h += MacGetTopBorderSize() + MacGetBottomBorderSize() ; #endif int actualWidth = width; @@ -1395,26 +1526,15 @@ 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 ) ; -#if TARGET_API_MAC_OSX + bool vis = m_peer->IsVisible(); + // 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 ) ; - HIRect hir = { r.left , r.top , r.right - r.left , r.bottom - r.top } ; - HIViewSetFrame ( (ControlRef) m_macControl , &hir ) ; - if ( vis ) - SetControlVisibility( (ControlRef)m_macControl , true , true ) ; -#else -// TODO TEST SetControlBounds( (ControlRef) m_macControl , &r ) ; + m_peer->SetVisibility( false , true ) ; + m_peer->SetRect( &r ) ; if ( vis ) - SetControlVisibility( (ControlRef)m_macControl , false , true ) ; - if ( doMove ) - MoveControl( (ControlRef) m_macControl , r.left , r.top ) ; - if ( doSize ) - SizeControl( (ControlRef) m_macControl , r.right-r.left , r.bottom-r.top ) ; - if ( vis ) - SetControlVisibility( (ControlRef)m_macControl , true , true ) ; -#endif + m_peer->SetVisibility( true , true ) ; + MacRepositionScrollBars() ; if ( doMove ) { @@ -1441,13 +1561,11 @@ wxSize wxWindowMac::DoGetBestSize() const return wxWindowBase::DoGetBestSize() ; Rect bestsize = { 0 , 0 , 0 , 0 } ; - short baselineoffset ; int bestWidth, bestHeight ; - ::GetBestControlRect( (ControlRef) m_macControl , &bestsize , &baselineoffset ) ; + m_peer->GetBestRect( &bestsize ) ; if ( EmptyRect( &bestsize ) ) { - baselineoffset = 0; bestsize.left = bestsize.top = 0 ; bestsize.right = 16 ; bestsize.bottom = 16 ; @@ -1471,7 +1589,6 @@ wxSize wxWindowMac::DoGetBestSize() const bestHeight = 13 ; return wxSize(bestWidth, bestHeight); -// return wxWindowBase::DoGetBestSize() ; } @@ -1550,13 +1667,18 @@ wxPoint wxWindowMac::GetClientAreaOrigin() const { RgnHandle rgn = NewRgn() ; Rect content ; - GetControlRegion( (ControlRef) m_macControl , kControlContentMetaPart , rgn ) ; + m_peer->GetRegion( 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 ; + m_peer->GetRect( &structure ) ; + OffsetRect( &content , -structure.left , -structure.top ) ; + } #endif return wxPoint( content.left + MacGetLeftBorderSize( ) , content.top + MacGetTopBorderSize( ) ); @@ -1581,9 +1703,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() ) ; + m_peer->SetTitle( m_label ) ; } Refresh() ; } @@ -1601,7 +1723,7 @@ bool wxWindowMac::Show(bool show) // TODO use visibilityChanged Carbon Event for OSX bool former = MacIsReallyShown() ; - SetControlVisibility( (ControlRef) m_macControl , show , true ) ; + m_peer->SetVisibility( show , true ) ; if ( former != MacIsReallyShown() ) MacPropagateVisibilityChanged() ; return TRUE; @@ -1609,15 +1731,12 @@ 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 ( enable ) - EnableControl( (ControlRef) m_macControl ) ; - else - DisableControl( (ControlRef) m_macControl ) ; + m_peer->Enable( enable ) ; if ( former != MacIsReallyEnabled() ) MacPropagateEnabledStateChanged() ; @@ -1700,8 +1819,9 @@ 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 ) ; -#else + if ( m_peer && m_peer->Ok() ) + return m_peer->IsVisible(); +#endif wxWindow* win = this ; while( win->IsShown() ) { @@ -1714,17 +1834,23 @@ bool wxWindowMac::MacIsReallyShown() } ; return false ; -#endif } bool wxWindowMac::MacIsReallyEnabled() { - return IsControlEnabled( (ControlRef) m_macControl ) ; + return m_peer->IsEnabled() ; } bool wxWindowMac::MacIsReallyHilited() { - return IsControlActive( (ControlRef) m_macControl ) ; + return m_peer->IsActive(); +} + +void wxWindowMac::MacFlashInvalidAreas() +{ +#if TARGET_API_MAC_OSX + HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ; +#endif } // @@ -1770,17 +1896,20 @@ void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect) { + if ( m_peer == NULL ) + return ; + #if TARGET_API_MAC_OSX if ( rect == NULL ) - HIViewSetNeedsDisplay( (ControlRef) m_macControl , true ) ; + m_peer->SetNeedsDisplay( true ) ; else { RgnHandle update = NewRgn() ; SetRectRgn( update , rect->x , rect->y , rect->x + rect->width , rect->y + rect->height ) ; SectRgn( (RgnHandle) MacGetVisibleRegion().GetWXHRGN() , update , update ) ; wxPoint origin = GetClientAreaOrigin() ; - OffsetRgn( update, origin.x , origin.y ) ; - HIViewSetNeedsDisplayInRegion( (ControlRef) m_macControl , update , true ) ; + OffsetRgn( update, origin.x , origin.y ) ; + m_peer->SetNeedsDisplay( true , update) ; } #else /* @@ -1797,16 +1926,16 @@ void wxWindowMac::Refresh(bool eraseBack, const wxRect *rect) InvalWindowRgn( (WindowRef) MacGetTopLevelWindowRef() , updateRgn ) ; DisposeRgn(updateRgn) ; */ - if ( IsControlVisible( (ControlRef) m_macControl ) ) + if ( m_peer->IsVisible()) { - SetControlVisibility( (ControlRef) m_macControl , false , false ) ; - SetControlVisibility( (ControlRef) m_macControl , true , true ) ; + m_peer->SetVisibility( false , false ) ; + m_peer->SetVisibility( true , true ) ; } /* if ( MacGetTopLevelWindow() == NULL ) return ; - if ( !IsControlVisible( (ControlRef) m_macControl ) ) + if ( !m_peer->IsVisible()) return ; wxPoint client = GetClientAreaOrigin(); @@ -1850,31 +1979,11 @@ void wxWindowMac::Freeze() #if TARGET_API_MAC_OSX if ( !m_frozenness++ ) { - HIViewSetDrawingEnabled( (HIViewRef) m_macControl , false ) ; + m_peer->SetDrawingEnabled( false ) ; } #endif } -#if TARGET_API_MAC_OSX -static void InvalidateControlAndChildren( HIViewRef control ) -{ - HIViewSetNeedsDisplay( control , true ) ; - UInt16 childrenCount = 0 ; - OSStatus err = CountSubControls( control , &childrenCount ) ; - if ( err == errControlIsNotEmbedder ) - return ; - wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ) ; - - for ( UInt16 i = childrenCount ; i >=1 ; --i ) - { - HIViewRef child ; - err = GetIndexedSubControl( control , i , & child ) ; - if ( err == errControlIsNotEmbedder ) - return ; - InvalidateControlAndChildren( child ) ; - } -} -#endif void wxWindowMac::Thaw() { @@ -1883,9 +1992,8 @@ void wxWindowMac::Thaw() if ( !--m_frozenness ) { - HIViewSetDrawingEnabled( (HIViewRef) m_macControl , true ) ; - InvalidateControlAndChildren( (HIViewRef) m_macControl ) ; - // HIViewSetNeedsDisplay( (HIViewRef) m_macControl , true ) ; + m_peer->SetDrawingEnabled( true ) ; + m_peer->InvalidateWithChildren() ; } #endif } @@ -1893,7 +2001,7 @@ void wxWindowMac::Thaw() void wxWindowMac::MacRedrawControl() { /* - if ( (ControlRef) m_macControl && MacGetTopLevelWindowRef() && IsControlVisible( (ControlRef) m_macControl ) ) + if ( *m_peer && MacGetTopLevelWindowRef() && m_peer->IsVisible()) { #if TARGET_API_MAC_CARBON Update() ; @@ -1902,7 +2010,7 @@ void wxWindowMac::MacRedrawControl() wxMacPortSetter helper(&dc) ; wxMacWindowClipper clipper(this) ; wxDC::MacSetupBackgroundForCurrentPort( MacGetBackgroundBrush() ) ; - UMADrawControl( (ControlRef) m_macControl ) ; + UMADrawControl( *m_peer ) ; #endif } */ @@ -1929,11 +2037,13 @@ void wxWindowMac::WarpPointer (int x_pos, int y_pos) void wxWindowMac::OnEraseBackground(wxEraseEvent& event) { +#if TARGET_API_MAC_OSX if ( m_macBackgroundBrush.Ok() == false || m_macBackgroundBrush.GetStyle() == wxTRANSPARENT ) { event.Skip() ; } else +#endif event.GetDC()->Clear() ; } @@ -2014,9 +2124,6 @@ void wxWindowMac::MacPaintBorders( int left , int top ) int major,minor; wxGetOsVersion( &major, &minor ); - RGBColor white = { 0xFFFF, 0xFFFF , 0xFFFF } ; - RGBColor face = { 0xDDDD, 0xDDDD , 0xDDDD } ; - RGBColor darkShadow = { 0x0000, 0x0000 , 0x0000 } ; RGBColor lightShadow = { 0x4444, 0x4444 , 0x4444 } ; // OS X has lighter border edges than classic: @@ -2034,19 +2141,18 @@ void wxWindowMac::MacPaintBorders( int left , int top ) int w , h ; GetSize( &w , &h ) ; + Rect rect = { top , left , h + top , w + left } ; if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) ) { #if wxMAC_USE_THEME_BORDER - Rect rect = { top , left , m_height + top , m_width + left } ; SInt32 border = 0 ; - /* - GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; + GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ; InsetRect( &rect , border , border ); - DrawThemeListBoxFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ; - */ - - DrawThemePrimaryGroup(&rect ,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ; + DrawThemeEditTextFrame(&rect,IsEnabled() ? kThemeStateActive : kThemeStateInactive) ; #else + RGBColor white = { 0xFFFF, 0xFFFF , 0xFFFF } ; + RGBColor face = { 0xDDDD, 0xDDDD , 0xDDDD } ; + bool sunken = HasFlag( wxSUNKEN_BORDER ) ; RGBForeColor( &face ); MoveTo( left + 0 , top + h - 2 ); @@ -2145,57 +2251,61 @@ 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 + wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , MacGetLeftBorderSize() + width , MacGetTopBorderSize() + height ) ; + if ( rect ) + { + scrollrect.Intersect( *rect ) ; + } + if ( m_peer->GetNeedsDisplay() ) + { + // 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 + m_peer->SetNeedsDisplay( true ) ; +#else + // this would be the preferred version for fast drawing controls + if( UMAGetSystemVersion() < 0x1030 ) + Update() ; + else + HIViewRender(*m_peer) ; +#endif + } + m_peer->ScrollRect( 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) ; + + m_peer->GetRect( &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 } @@ -2221,9 +2331,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 ) @@ -2259,7 +2366,9 @@ void wxWindowMac::MacOnScroll(wxScrollEvent &event ) // Get the window with the focus wxWindowMac *wxWindowBase::FindFocus() { - return gFocusWindow ; + ControlRef control ; + GetKeyboardFocus( GetUserFocusWindow() , &control ) ; + return wxFindControlFromMacControl( control ) ; } void wxWindowMac::OnSetFocus(wxFocusEvent& event) @@ -2275,6 +2384,25 @@ void wxWindowMac::OnSetFocus(wxFocusEvent& event) //wxChildFocusEvent eventFocus(this); //(void)GetEventHandler()->ProcessEvent(eventFocus); + if ( MacGetTopLevelWindow() && m_peer->NeedsFocusRect() ) + { + wxMacWindowStateSaver sv( this ) ; +// wxWindowDC dc(this) ; +// wxMacPortSetter helper(&dc) ; + + int w , h ; + int x , y ; + x = y = 0 ; + MacWindowToRootWindow( &x , &y ) ; + GetSize( &w , &h ) ; + Rect rect = {y , x , h + y , w + x } ; + + if ( event.GetEventType() == wxEVT_SET_FOCUS ) + DrawThemeFocusRect( &rect , true ) ; + else + DrawThemeFocusRect( &rect , false ) ; + } + event.Skip(); } @@ -2289,11 +2417,13 @@ void wxWindowMac::OnInternalIdle() // Raise the window to the top of the Z order void wxWindowMac::Raise() { + m_peer->SetZOrder( true , NULL ) ; } // Lower the window to the bottom of the Z order void wxWindowMac::Lower() { + m_peer->SetZOrder( false , NULL ) ; } @@ -2353,9 +2483,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 + m_peer->SetNeedsDisplay( true ) ; + } #else - ::Draw1Control( (ControlRef) m_macControl ) ; + ::Draw1Control( m_peer->GetControlRef() ) ; #endif } @@ -2375,9 +2535,14 @@ wxRegion wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures ) Rect r ; RgnHandle visRgn = NewRgn() ; RgnHandle tempRgn = NewRgn() ; - if ( IsControlVisible( (ControlRef) m_macControl ) ) + if ( m_peer->IsVisible()) { - GetControlBounds( (ControlRef) m_macControl , &r ) ; + m_peer->GetRect( &r ) ; + r.left -= MacGetLeftBorderSize() ; + r.top -= MacGetTopBorderSize() ; + r.bottom += MacGetBottomBorderSize() ; + r.right += MacGetRightBorderSize() ; + if (! MacGetTopLevelWindow()->MacUsesCompositing() ) { MacRootWindowToWindow( &r.left , & r.top ) ; @@ -2501,7 +2666,7 @@ void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase) if ( MacGetTopLevelWindow()->MacUsesCompositing() == false ) { Rect bounds; - UMAGetControlBoundsInWindowCoords( (ControlRef)m_macControl, &bounds ); + m_peer->GetRectInWindowCoords( &bounds ); RgnHandle controlRgn = NewRgn(); RectRgn( controlRgn, &bounds ); //KO: This sets the ownUpdateRgn to the area of this control that is inside @@ -2537,6 +2702,8 @@ void wxWindowMac::MacCreateScrollBars( long style ) { wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ; +#if 0 + bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ; int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1: 0 ; int width, height ; @@ -2567,6 +2734,34 @@ void wxWindowMac::MacCreateScrollBars( long style ) { m_hScrollBar->Show(false) ; } +#else + if ( style & ( wxVSCROLL | wxHSCROLL ) ) + { + bool hasBoth = ( style & wxVSCROLL ) && ( style & wxHSCROLL ) ; + int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1: 0 ; + int width, height ; + GetClientSize( &width , &height ) ; + + wxPoint vPoint(width-MAC_SCROLLBAR_SIZE, 0) ; + wxSize vSize(MAC_SCROLLBAR_SIZE, height - adjust) ; + wxPoint hPoint(0 , height-MAC_SCROLLBAR_SIZE ) ; + wxSize hSize( width - adjust, MAC_SCROLLBAR_SIZE) ; + + + if ( style & wxVSCROLL ) + { + m_vScrollBar = new wxScrollBar(this, wxWINDOW_VSCROLL, vPoint, + vSize , wxVERTICAL); + } + + if ( style & wxHSCROLL ) + { + m_hScrollBar = new wxScrollBar(this, wxWINDOW_HSCROLL, hPoint, + hSize , wxHORIZONTAL); + } + } +#endif + // because the create does not take into account the client area origin MacRepositionScrollBars() ; // we might have a real position shift @@ -2574,6 +2769,9 @@ void wxWindowMac::MacCreateScrollBars( long style ) void wxWindowMac::MacRepositionScrollBars() { + if ( !m_hScrollBar && !m_vScrollBar ) + return ; + bool hasBoth = ( m_hScrollBar && m_hScrollBar->IsShown()) && ( m_vScrollBar && m_vScrollBar->IsShown()) ; int adjust = hasBoth ? MAC_SCROLLBAR_SIZE - 1 : 0 ; @@ -2686,7 +2884,7 @@ long wxWindowMac::MacGetLeftBorderSize( ) const if (m_windowStyle & wxRAISED_BORDER || m_windowStyle & wxSUNKEN_BORDER ) { SInt32 border = 3 ; -#if wxMAC_USE_THEME_BORDER +#if 0 // wxMAC_USE_THEME_BORDER GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; #endif return border ; @@ -2694,8 +2892,8 @@ long wxWindowMac::MacGetLeftBorderSize( ) const else if ( m_windowStyle &wxDOUBLE_BORDER) { SInt32 border = 3 ; -#if wxMAC_USE_THEME_BORDER - GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; +#if 0 // wxMAC_USE_THEME_BORDER + GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ; #endif return border ; } @@ -2763,62 +2961,6 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) if ( ! GetEventHandler()->ProcessEvent(evtCtx) ) event.Skip() ; } - else if (event.GetEventType() == wxEVT_LEFT_DOWN || event.GetEventType() == wxEVT_LEFT_DCLICK ) - { - - int x = event.m_x ; - int y = event.m_y ; - - if ( MacGetTopLevelWindow()->MacUsesCompositing() == false ) - { - // OS Needs it in tlw content area coordinates - MacClientToRootWindow( &x , &y ) ; - } - else - { - // OS Needs it in window not client coordinates - wxPoint origin = GetClientAreaOrigin() ; - x += origin.x ; - y += origin.y ; - } - Point localwhere ; - SInt16 controlpart ; - - localwhere.h = x ; - localwhere.v = y ; - - short modifiers = 0; - - if ( !event.m_leftDown && !event.m_rightDown ) - modifiers |= btnState ; - - if ( event.m_shiftDown ) - modifiers |= shiftKey ; - - if ( event.m_controlDown ) - modifiers |= controlKey ; - - if ( event.m_altDown ) - modifiers |= optionKey ; - - if ( event.m_metaDown ) - modifiers |= cmdKey ; - - bool handled = false ; - - if ( ::IsControlActive( (ControlRef) m_macControl ) ) - { - controlpart = ::HandleControlClick( (ControlRef) m_macControl , localwhere , modifiers , (ControlActionUPP) -1 ) ; - wxTheApp->s_lastMouseDown = 0 ; - if ( controlpart != kControlNoPart ) - { - MacHandleControlClick((WXWidget) (ControlRef) m_macControl , controlpart , false /* mouse not down anymore */ ) ; - handled = true ; - } - } - if ( !handled ) - event.Skip() ; - } else { event.Skip() ; @@ -2827,7 +2969,6 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) void wxWindowMac::MacHandleControlClick( WXWidget control , wxInt16 controlpart , bool WXUNUSED( mouseStillDown ) ) { - wxASSERT_MSG( (ControlRef) m_macControl != NULL , wxT("No valid mac control") ) ; } Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin ) @@ -2839,4 +2980,9 @@ Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxS return bounds ; } +wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) +{ + return eventNotHandledErr ; +} +