X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1f0c8f31f407ecfce909060464c0ea655221cdab..bd044e27b3c7f9b6d56e75b9e1b789be3545cd5e:/src/osx/carbon/window.cpp?ds=sidebyside diff --git a/src/osx/carbon/window.cpp b/src/osx/carbon/window.cpp index 20619b2b08..1e54d5a279 100644 --- a/src/osx/carbon/window.cpp +++ b/src/osx/carbon/window.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: src/mac/carbon/window.cpp +// Name: src/osx/carbon/window.cpp // Purpose: wxWindowMac // Author: Stefan Csomor // Modified by: @@ -61,76 +61,30 @@ #include "wx/dnd.h" #endif +#if wxOSX_USE_CARBON #include "wx/osx/uma.h" +#else +#include "wx/osx/private.h" +// bring in theming +#include +#endif #define MAC_SCROLLBAR_SIZE 15 #define MAC_SMALL_SCROLLBAR_SIZE 11 #include -#ifdef __WXUNIVERSAL__ - IMPLEMENT_ABSTRACT_CLASS(wxWindowMac, wxWindowBase) -#else - IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) -#endif - -BEGIN_EVENT_TABLE(wxWindowMac, wxWindowBase) - EVT_NC_PAINT(wxWindowMac::OnNcPaint) - EVT_ERASE_BACKGROUND(wxWindowMac::OnEraseBackground) - EVT_PAINT(wxWindowMac::OnPaint) - EVT_MOUSE_EVENTS(wxWindowMac::OnMouseEvent) -END_EVENT_TABLE() - #define wxMAC_DEBUG_REDRAW 0 #ifndef wxMAC_DEBUG_REDRAW #define wxMAC_DEBUG_REDRAW 0 #endif -// --------------------------------------------------------------------------- -// Utility Routines to move between different coordinate systems -// --------------------------------------------------------------------------- - -/* - * Right now we have the following setup : - * a border that is not part of the native control is always outside the - * control's border (otherwise we loose all native intelligence, future ways - * may be to have a second embedding control responsible for drawing borders - * and backgrounds eventually) - * so all this border calculations have to be taken into account when calling - * native methods or getting native oriented data - * so we have three coordinate systems here - * wx client coordinates - * wx window coordinates (including window frames) - * native coordinates - */ - -// -// originating from native control -// - - -void wxMacNativeToWindow( const wxWindow* window , RgnHandle handle ) -{ - OffsetRgn( handle , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ; -} - -void wxMacNativeToWindow( const wxWindow* window , Rect *rect ) -{ - OffsetRect( rect , window->MacGetLeftBorderSize() , window->MacGetTopBorderSize() ) ; -} - -// -// directed towards native control -// - -void wxMacWindowToNative( const wxWindow* window , RgnHandle handle ) -{ - OffsetRgn( handle , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ); -} - -void wxMacWindowToNative( const wxWindow* window , Rect *rect ) +// Get the window with the focus +WXWidget wxWidgetImpl::FindFocus() { - OffsetRect( rect , -window->MacGetLeftBorderSize() , -window->MacGetTopBorderSize() ) ; + ControlRef control = NULL ; + GetKeyboardFocus( GetUserFocusWindow() , &control ) ; + return control; } // --------------------------------------------------------------------------- @@ -185,24 +139,23 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl { case kEventControlDraw : { - RgnHandle updateRgn = NULL ; - RgnHandle allocatedRgn = NULL ; + HIShapeRef updateRgn = NULL ; + HIMutableShapeRef allocatedRgn = NULL ; wxRegion visRegion = thisWindow->MacGetVisibleRegion() ; - if ( cEvent.GetParameter(kEventParamRgnHandle, &updateRgn) != noErr ) + // according to the docs: redraw entire control if param not present + if ( cEvent.GetParameter(kEventParamShape, &updateRgn) != noErr ) { - HIShapeGetAsQDRgn( visRegion.GetWXHRGN(), updateRgn ); + updateRgn = visRegion.GetWXHRGN(); } 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 ) ; - + allocatedRgn = HIShapeCreateMutableCopy(updateRgn); + HIShapeOffset(allocatedRgn, thisWindow->MacGetLeftBorderSize() , thisWindow->MacGetTopBorderSize()); // hide the given region by the new region that must be shifted - wxMacNativeToWindow( thisWindow , allocatedRgn ) ; updateRgn = allocatedRgn ; } } @@ -231,7 +184,6 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl #endif { - bool created = false ; CGContextRef cgContext = NULL ; OSStatus err = cEvent.GetParameter(kEventParamCGContextRef, &cgContext) ; if ( err != noErr ) @@ -255,7 +207,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl iter = iter->GetParent() ; } } - CGContextSetAlpha( cgContext , alpha ) ; + CGContextSetAlpha( cgContext, alpha ) ; if ( thisWindow->GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) { @@ -264,20 +216,36 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl CGContextClearRect( cgContext, bounds ); } - - - if ( thisWindow->MacDoRedraw( updateRgn , cEvent.GetTicks() ) ) - result = noErr ; - + if ( !HIShapeIsEmpty(updateRgn) ) + { + // refcount increase because wxRegion constructor takes ownership of the native region + CFRetain(updateRgn); + thisWindow->GetUpdateRegion() = wxRegion(updateRgn); + if ( !thisWindow->MacDoRedraw( cEvent.GetTicks() ) ) + { + // for native controls: call their native paint method + if ( !thisWindow->MacIsUserPane() || + ( thisWindow->IsTopLevel() && thisWindow->GetBackgroundStyle() == wxBG_STYLE_SYSTEM ) ) + { + if ( thisWindow->GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT ) + { + CallNextEventHandler( handler,event ) ; + result = noErr ; + } + } + } + else + { + result = noErr ; + } + thisWindow->MacPaintChildrenBorders(); + } thisWindow->MacSetCGContextRef( NULL ) ; } - - if ( created ) - CGContextRelease( cgContext ) ; } if ( allocatedRgn ) - DisposeRgn( allocatedRgn ) ; + CFRelease( allocatedRgn ) ; } break ; @@ -341,7 +309,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl thisWindow->GetCaret()->OnKillFocus(); #endif - wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow)); + wxLogTrace(wxT("Focus"), wxT("focus lost(%p)"), static_cast(thisWindow)); // remove this as soon as posting the synthesized event works properly static bool inKillFocusEvent = false ; @@ -361,7 +329,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl { // set focus // panel wants to track the window which was the last to have focus in it - wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow)); + wxLogTrace(wxT("Focus"), wxT("focus set(%p)"), static_cast(thisWindow)); wxChildFocusEvent eventFocus((wxWindow*)thisWindow); thisWindow->HandleWindowEvent(eventFocus); @@ -389,14 +357,14 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl if ( controlPart != kControlFocusNoPart ) { targetFocusWindow = thisWindow; - wxLogTrace(_T("Focus"), _T("focus to be set(%p)"), wx_static_cast(void*, thisWindow)); + wxLogTrace(wxT("Focus"), wxT("focus to be set(%p)"), static_cast(thisWindow)); } else { formerFocusWindow = thisWindow; - wxLogTrace(_T("Focus"), _T("focus to be lost(%p)"), wx_static_cast(void*, thisWindow)); + wxLogTrace(wxT("Focus"), wxT("focus to be lost(%p)"), static_cast(thisWindow)); } - + ControlPartCode previousControlPart = 0; verify_noerr( HIViewGetFocusPart(controlRef, &previousControlPart)); @@ -429,7 +397,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl iEvent.SetParameter( kEventParamPostTarget, typeEventTargetRef, GetControlEventTarget( controlRef ) ); iEvent.SetParameter( kEventParamControlPreviousPart, typeControlPartCode, previousControlPart ); iEvent.SetParameter( kEventParamControlCurrentPart, typeControlPartCode, currentControlPart ); - + #if 1 // TODO test this first, avoid double posts etc... PostEventToQueue( GetMainEventQueue(), evRef , kEventPriorityHigh ); @@ -447,7 +415,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl thisWindow->GetCaret()->OnKillFocus(); #endif - wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow)); + wxLogTrace(wxT("Focus"), wxT("focus lost(%p)"), static_cast(thisWindow)); static bool inKillFocusEvent = false ; @@ -463,7 +431,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl else { // panel wants to track the window which was the last to have focus in it - wxLogTrace(_T("Focus"), _T("focus set(%p)"), wx_static_cast(void*, thisWindow)); + wxLogTrace(wxT("Focus"), wxT("focus set(%p)"), static_cast(thisWindow)); wxChildFocusEvent eventFocus((wxWindow*)thisWindow); thisWindow->HandleWindowEvent(eventFocus); @@ -491,7 +459,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl WindowRef owner = cEvent.GetParameter(kEventParamWindowRef); if ( !IsWindowActive(owner) ) { - cEvent.SetParameter(kEventParamClickActivation,(UInt32) kActivateAndIgnoreClick) ; + cEvent.SetParameter(kEventParamClickActivation,typeClickActivationResult, (UInt32) kActivateAndIgnoreClick) ; result = noErr ; } } @@ -753,7 +721,6 @@ wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler), wxMenuItem* item = NULL ; wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ; - int id = wxMacCommandToId( command.commandID ) ; if ( item ) { @@ -762,11 +729,13 @@ wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler), switch ( cEvent.GetKind() ) { case kEventProcessCommand : - result = itemMenu->MacHandleCommandProcess( item, id, focus ); + if ( itemMenu->HandleCommandProcess( item, focus ) ) + result = noErr; break ; case kEventCommandUpdateStatus: - result = itemMenu->MacHandleCommandUpdateStatus( item, id, focus ); + if ( itemMenu->HandleCommandUpdateStatus( item, focus ) ) + result = noErr; break ; default : @@ -821,357 +790,260 @@ pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode p { if ( partCode != 0) { - wxWindow* wx = wxFindControlFromMacControl( control ) ; + wxWindow* wx = wxFindWindowFromWXWidget( (WXWidget) control ) ; if ( wx ) - wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ; - } -} -wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ; - -// =========================================================================== -// implementation -// =========================================================================== + { + wxEventType scrollEvent = wxEVT_NULL; + switch ( partCode ) + { + case kControlUpButtonPart: + scrollEvent = wxEVT_SCROLL_LINEUP; + break; -WX_DECLARE_HASH_MAP(ControlRef, wxWindow*, wxPointerHash, wxPointerEqual, MacControlMap); + case kControlDownButtonPart: + scrollEvent = wxEVT_SCROLL_LINEDOWN; + break; -static MacControlMap wxWinMacControlList; + case kControlPageUpPart: + scrollEvent = wxEVT_SCROLL_PAGEUP; + break; -wxWindow *wxFindControlFromMacControl(ControlRef inControl ) -{ - MacControlMap::iterator node = wxWinMacControlList.find(inControl); + case kControlPageDownPart: + scrollEvent = wxEVT_SCROLL_PAGEDOWN; + break; - return (node == wxWinMacControlList.end()) ? NULL : node->second; + case kControlIndicatorPart: + scrollEvent = wxEVT_SCROLL_THUMBTRACK; + // when this is called as a live proc, mouse is always still down + // so no need for thumbrelease + // scrollEvent = wxEVT_SCROLL_THUMBRELEASE; + break; + } + wx->TriggerScrollEvent(scrollEvent) ; + } + } } +wxMAC_DEFINE_PROC_GETTER( ControlActionUPP , wxMacLiveScrollbarActionProc ) ; -void wxAssociateControlWithMacControl(ControlRef inControl, wxWindow *control) -{ - // adding NULL ControlRef is (first) surely a result of an error and - // (secondly) breaks native event processing - wxCHECK_RET( inControl != (ControlRef) NULL, wxT("attempt to add a NULL WindowRef to window list") ); +wxWidgetImplType* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, + wxWindowMac* WXUNUSED(parent), + wxWindowID WXUNUSED(id), + const wxPoint& pos, + const wxSize& size, + long WXUNUSED(style), + long WXUNUSED(extraStyle)) +{ + OSStatus err = noErr; + Rect bounds = wxMacGetBoundsForControl( wxpeer , pos , size ) ; + wxMacControl* c = new wxMacControl(wxpeer) ; + UInt32 features = 0 + | kControlSupportsEmbedding + | kControlSupportsLiveFeedback + | kControlGetsFocusOnClick +// | kControlHasSpecialBackground +// | kControlSupportsCalcBestRect + | kControlHandlesTracking + | kControlSupportsFocus + | kControlWantsActivate + | kControlWantsIdle ; - wxWinMacControlList[inControl] = control; + err =::CreateUserPaneControl( MAC_WXHWND(wxpeer->GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , c->GetControlRefAddr() ); + verify_noerr( err ); + return c; } -void wxRemoveMacControlAssociation(wxWindow *control) -{ - // iterate over all the elements in the class - // is the iterator stable ? as we might have two associations pointing to the same wxWindow - // we should go on... - bool found = true ; - while ( found ) - { - found = false ; - MacControlMap::iterator it; - for ( it = wxWinMacControlList.begin(); it != wxWinMacControlList.end(); ++it ) - { - if ( it->second == control ) - { - wxWinMacControlList.erase(it); - found = true ; - break; - } - } - } +void wxMacControl::InstallEventHandler( WXWidget control ) +{ + wxWidgetImpl::Associate( control ? control : (WXWidget) m_controlRef , this ) ; + ::InstallControlEventHandler( control ? (ControlRef) control : m_controlRef , GetwxMacWindowEventHandlerUPP(), + GetEventTypeCount(eventList), eventList, GetWXPeer(), NULL); } -// ---------------------------------------------------------------------------- - // constructors and such -// ---------------------------------------------------------------------------- +IMPLEMENT_DYNAMIC_CLASS( wxMacControl , wxWidgetImpl ) -wxWindowMac::wxWindowMac() +wxMacControl::wxMacControl() { Init(); } -wxWindowMac::wxWindowMac(wxWindowMac *parent, - wxWindowID id, - const wxPoint& pos , - const wxSize& size , - long style , - const wxString& name ) +wxMacControl::wxMacControl(wxWindowMac* peer , bool isRootControl ) : + wxWidgetImpl( peer, isRootControl ) { Init(); - Create(parent, id, pos, size, style, name); } -void wxWindowMac::Init() +wxMacControl::~wxMacControl() { - m_peer = NULL ; - m_macAlpha = 255 ; - m_cgContextRef = NULL ; - - // as all windows are created with WS_VISIBLE style... - m_isShown = true; - - m_hScrollBar = NULL ; - m_vScrollBar = NULL ; - m_hScrollBarAlwaysShown = false; - m_vScrollBarAlwaysShown = false; + if ( m_controlRef && !IsRootControl() ) + { + wxASSERT_MSG( m_controlRef != NULL , wxT("Control Handle already NULL, Dispose called twice ?") ); + wxASSERT_MSG( IsValidControlHandle(m_controlRef) , wxT("Invalid Control Handle (maybe already released) in Dispose") ); - m_macIsUserPane = true; - m_clipChildren = false ; - m_cachedClippedRectValid = false ; + wxWidgetImpl::RemoveAssociations( this ) ; + // we cannot check the ref count here anymore, as autorelease objects might delete their refs later + // we can have situations when being embedded, where the control gets deleted behind our back, so only + // CFRelease if we are safe + if ( IsValidControlHandle(m_controlRef) ) + CFRelease(m_controlRef); + } + m_controlRef = NULL; } -wxWindowMac::~wxWindowMac() +void wxMacControl::Init() { - SendDestroyEvent(); - - m_isBeingDeleted = true; - - MacInvalidateBorders() ; - -#ifndef __WXUNIVERSAL__ - // VS: make sure there's no wxFrame with last focus set to us: - for ( wxWindow *win = GetParent(); win; win = win->GetParent() ) - { - wxFrame *frame = wxDynamicCast(win, wxFrame); - if ( frame ) - { - if ( frame->GetLastFocus() == this ) - frame->SetLastFocus((wxWindow*)NULL); - break; - } - } -#endif - - // destroy children before destroying this window itself - DestroyChildren(); - - // wxRemoveMacControlAssociation( this ) ; - // If we delete an item, we should initialize the parent panel, - // because it could now be invalid. - wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(this), wxTopLevelWindow); - if ( tlw ) - { - if ( tlw->GetDefaultItem() == (wxButton*) this) - tlw->SetDefaultItem(NULL); - } + m_controlRef = NULL; + m_macControlEventHandler = NULL; +} - if ( m_peer && m_peer->Ok() ) - { - // in case the callback might be called during destruction - wxRemoveMacControlAssociation( this) ; - ::RemoveEventHandler( (EventHandlerRef ) m_macControlEventHandler ) ; - // we currently are not using this hook - // ::SetControlColorProc( *m_peer , NULL ) ; - m_peer->Dispose() ; - } +void wxMacControl::RemoveFromParent() +{ + // nothing to do here for carbon + HIViewRemoveFromSuperview(m_controlRef); +} - if ( g_MacLastWindow == this ) - g_MacLastWindow = NULL ; +void wxMacControl::Embed( wxWidgetImpl *parent ) +{ + HIViewAddSubview((ControlRef)parent->GetWXWidget(), m_controlRef); +} -#ifndef __WXUNIVERSAL__ - wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( (wxWindow*)this ) , wxFrame ) ; - if ( frame ) - { - if ( frame->GetLastFocus() == this ) - frame->SetLastFocus( NULL ) ; - } -#endif +void wxMacControl::SetNeedsDisplay( const wxRect* rect ) +{ + if ( !IsVisible() ) + return; - // delete our drop target if we've got one -#if wxUSE_DRAG_AND_DROP - if ( m_dropTarget != NULL ) + if ( rect != NULL ) { - delete m_dropTarget; - m_dropTarget = NULL; + HIRect updatearea = CGRectMake( rect->x , rect->y , rect->width , rect->height); + HIViewSetNeedsDisplayInRect( m_controlRef, &updatearea, true ); } -#endif - - delete m_peer ; + else + HIViewSetNeedsDisplay( m_controlRef , true ); } -WXWidget wxWindowMac::GetHandle() const +void wxMacControl::Raise() { - return (WXWidget) m_peer->GetControlRef() ; + verify_noerr( HIViewSetZOrder( m_controlRef, kHIViewZOrderAbove, NULL ) ); } -void wxWindowMac::MacInstallEventHandler( WXWidget control ) +void wxMacControl::Lower() { - wxAssociateControlWithMacControl( (ControlRef) control , this ) ; - InstallControlEventHandler( (ControlRef)control , GetwxMacWindowEventHandlerUPP(), - GetEventTypeCount(eventList), eventList, this, - (EventHandlerRef *)&m_macControlEventHandler); + verify_noerr( HIViewSetZOrder( m_controlRef, kHIViewZOrderBelow, NULL ) ); } -// Constructor -bool wxWindowMac::Create(wxWindowMac *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) +void wxMacControl::GetContentArea(int &left , int &top , int &width , int &height) const { - wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") ); - - if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) - return false; - - m_windowVariant = parent->GetWindowVariant() ; + HIShapeRef rgn = NULL; + Rect content ; - if ( m_macIsUserPane ) + if ( HIViewCopyShape(m_controlRef, kHIViewContentMetaPart, &rgn) == noErr) { - Rect bounds = wxMacGetBoundsForControl( this , pos , size ) ; - - UInt32 features = 0 - | kControlSupportsEmbedding - | kControlSupportsLiveFeedback - | kControlGetsFocusOnClick -// | kControlHasSpecialBackground -// | kControlSupportsCalcBestRect - | kControlHandlesTracking - | kControlSupportsFocus - | kControlWantsActivate - | kControlWantsIdle ; - - m_peer = new wxMacControl(this) ; - OSStatus err =::CreateUserPaneControl( MAC_WXHWND(GetParent()->MacGetTopLevelWindowRef()) , &bounds, features , m_peer->GetControlRefAddr() ); - verify_noerr( err ); - - MacPostControlCreate(pos, size) ; + CGRect cgrect; + HIShapeGetBounds(rgn, &cgrect); + content = (Rect){ (short)cgrect.origin.y, + (short)cgrect.origin.x, + (short)(cgrect.origin.y+cgrect.size.height), + (short)(cgrect.origin.x+cgrect.size.width) }; + CFRelease(rgn); } - -#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)))) + else { - MacCreateScrollBars( style ) ; + GetControlBounds(m_controlRef, &content); + content.right -= content.left; + content.left = 0; + content.bottom -= content.top; + content.top = 0; } -#endif - wxWindowCreateEvent event(this); - GetEventHandler()->AddPendingEvent(event); + left = content.left; + top = content.top; - return true; + width = content.right - content.left ; + height = content.bottom - content.top ; } -void wxWindowMac::MacChildAdded() +void wxMacControl::Move(int x, int y, int width, int height) { - if ( m_vScrollBar ) - m_vScrollBar->Raise() ; - if ( m_hScrollBar ) - m_hScrollBar->Raise() ; + HIRect hir = CGRectMake(x,y,width,height); + HIViewSetFrame ( m_controlRef , &hir ); } -void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSize& size) +void wxMacControl::GetPosition( int &x, int &y ) const { - wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ; - - m_peer->SetReference( (URefCon) this ) ; - GetParent()->AddChild( this ); - - MacInstallEventHandler( (WXWidget) m_peer->GetControlRef() ); - - ControlRef container = (ControlRef) GetParent()->GetHandle() ; - wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; - ::EmbedControl( m_peer->GetControlRef() , container ) ; - GetParent()->MacChildAdded() ; - - // adjust font, controlsize etc - DoSetWindowVariant( m_windowVariant ) ; - - m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; - - if (!m_macIsUserPane) - SetInitialSize(size); - - SetCursor( *wxSTANDARD_CURSOR ) ; + Rect r; + GetControlBounds( m_controlRef , &r ); + x = r.left; + y = r.top; } -void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) +void wxMacControl::GetSize( int &width, int &height ) const { - // Don't assert, in case we set the window variant before - // the window is created - // wxASSERT( m_peer->Ok() ) ; - - m_windowVariant = variant ; - - if (m_peer == NULL || !m_peer->Ok()) - return; + Rect r; + GetControlBounds( m_controlRef , &r ); + width = r.right - r.left; + height = r.bottom - r.top; +} +void wxMacControl::SetControlSize( wxWindowVariant variant ) +{ ControlSize size ; - ThemeFontID themeFont = kThemeSystemFont ; - - // we will get that from the settings later - // and make this NORMAL later, but first - // we have a few calculations that we must fix - switch ( variant ) { case wxWINDOW_VARIANT_NORMAL : size = kControlSizeNormal; - themeFont = kThemeSystemFont ; break ; case wxWINDOW_VARIANT_SMALL : size = kControlSizeSmall; - themeFont = kThemeSmallSystemFont ; break ; case wxWINDOW_VARIANT_MINI : // not always defined in the headers size = 3 ; - themeFont = 109 ; break ; case wxWINDOW_VARIANT_LARGE : size = kControlSizeLarge; - themeFont = kThemeSystemFont ; break ; default: - wxFAIL_MSG(_T("unexpected window variant")); + wxFAIL_MSG(wxT("unexpected window variant")); break ; } - m_peer->SetData(kControlEntireControl, kControlSizeTag, &size ) ; - - wxFont font ; - font.MacCreateFromThemeFont( themeFont ) ; - SetFont( font ) ; -} - -void wxWindowMac::MacUpdateControlFont() -{ - m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; - // do not trigger refreshes upon invisible and possible partly created objects - if ( IsShownOnScreen() ) - Refresh() ; -} - -bool wxWindowMac::SetFont(const wxFont& font) -{ - bool retval = wxWindowBase::SetFont( font ); - - MacUpdateControlFont() ; - - return retval; + SetData(kControlEntireControl, kControlSizeTag, &size ) ; } -bool wxWindowMac::SetForegroundColour(const wxColour& col ) +void wxMacControl::ScrollRect( const wxRect *rect, int dx, int dy ) { - bool retval = wxWindowBase::SetForegroundColour( col ); - - if (retval) - MacUpdateControlFont(); - - return retval; -} + if (GetNeedsDisplay() ) + { + // 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 + SetNeedsDisplay() ; +#else + // this would be the preferred version for fast drawing controls + HIViewRender(GetControlRef()) ; +#endif + } -bool wxWindowMac::SetBackgroundColour(const wxColour& col ) -{ - if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol ) - return false ; + // note there currently is a bug in OSX (10.3 +?) 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 - m_peer->SetBackgroundColour( col ) ; + HIRect scrollarea = CGRectMake( rect->x , rect->y , rect->width , rect->height); + HIViewScrollRect ( m_controlRef , &scrollarea , dx ,dy ); - return true ; +#if 0 + // this would be the preferred version for fast drawing controls + HIViewRender(GetControlRef()) ; +#endif } -bool wxWindowMac::MacCanFocus() const +bool wxMacControl::CanFocus() const { // 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, @@ -1187,2091 +1059,462 @@ bool wxWindowMac::MacCanFocus() const else { UInt32 features = 0 ; - m_peer->GetFeatures( &features ) ; + GetControlFeatures( m_controlRef, &features ) ; return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ; } } -void wxWindowMac::SetFocus() +bool wxMacControl::GetNeedsDisplay() const +{ + return HIViewGetNeedsDisplay( m_controlRef ); +} + +void wxWidgetImpl::Convert( wxPoint *pt , wxWidgetImpl *from , wxWidgetImpl *to ) { - if ( !AcceptsFocus() ) - return ; + HIPoint hiPoint; - wxWindow* former = FindFocus() ; - if ( former == this ) - return ; + hiPoint.x = pt->x; + hiPoint.y = pt->y; + HIViewConvertPoint( &hiPoint , (ControlRef) from->GetWXWidget() , (ControlRef) to->GetWXWidget() ); + pt->x = (int)hiPoint.x; + pt->y = (int)hiPoint.y; +} +bool wxMacControl::SetFocus() +{ // 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 - wxLogTrace(_T("Focus"), _T("before wxWindow::SetFocus(%p) %d"), wx_static_cast(void*, this), GetName().c_str()); - OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ; + + OSStatus err = SetKeyboardFocus( GetControlOwner( m_controlRef ), m_controlRef, kControlFocusNextPart ); if ( err == errCouldntSetFocus ) - { - wxLogTrace(_T("Focus"), _T("in wxWindow::SetFocus(%p) errCouldntSetFocus"), wx_static_cast(void*, this)); - return ; - } - wxLogTrace(_T("Focus"), _T("after wxWindow::SetFocus(%p)"), wx_static_cast(void*, this)); + return false ; + SetUserFocusWindow(GetControlOwner( m_controlRef ) ); - SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() ); + return true; } -void wxWindowMac::DoCaptureMouse() +bool wxMacControl::HasFocus() const { - wxApp::s_captureWindow = this ; + ControlRef control; + GetKeyboardFocus( GetUserFocusWindow() , &control ); + return control == m_controlRef; } -wxWindow * wxWindowBase::GetCapture() +void wxMacControl::SetCursor(const wxCursor& cursor) { - return wxApp::s_captureWindow ; + wxWindowMac *mouseWin = 0 ; + WindowRef window = GetControlOwner( m_controlRef ) ; + + wxNonOwnedWindow* tlwwx = wxNonOwnedWindow::GetFromWXWindow( (WXWindow) window ) ; + if ( tlwwx != NULL ) + { + ControlPartCode part ; + ControlRef control ; + 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; + tlwwx->ScreenToClient(&x, &y); + pt.h = x; + pt.v = y; +#endif + control = FindControlUnderMouse( pt , window , &part ) ; + if ( control ) + mouseWin = wxFindWindowFromWXWidget( (WXWidget) control ) ; + } + + if ( mouseWin == tlwwx && !wxIsBusy() ) + cursor.MacInstall() ; } -void wxWindowMac::DoReleaseMouse() +void wxMacControl::CaptureMouse() { - wxApp::s_captureWindow = NULL ; } -#if wxUSE_DRAG_AND_DROP - -void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget) +void wxMacControl::ReleaseMouse() { - if ( m_dropTarget != NULL ) - delete m_dropTarget; - - m_dropTarget = pDropTarget; - if ( m_dropTarget != NULL ) - { - // TODO: - } } -#endif +// +// subclass specifics +// -// Old-style File Manager Drag & Drop -void wxWindowMac::DragAcceptFiles(bool WXUNUSED(accept)) +OSStatus wxMacControl::GetData(ControlPartCode inPartCode , ResType inTag , Size inBufferSize , void * inOutBuffer , Size * outActualSize ) const { - // TODO: + return ::GetControlData( m_controlRef , inPartCode , inTag , inBufferSize , inOutBuffer , outActualSize ); } -// 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& WXUNUSED(x), - int& WXUNUSED(y), - int& WXUNUSED(w), - int& WXUNUSED(h)) const +OSStatus wxMacControl::GetDataSize(ControlPartCode inPartCode , ResType inTag , Size * outActualSize ) const { - wxFAIL_MSG( wxT("Not currently supported") ) ; + return ::GetControlDataSize( m_controlRef , inPartCode , inTag , outActualSize ); } -// From a wx position / size calculate the appropriate size of the native control - -bool wxWindowMac::MacGetBoundsForControl( - const wxPoint& pos, - const wxSize& size, - int& x, int& y, - int& w, int& h , bool adjustOrigin ) const +OSStatus wxMacControl::SetData(ControlPartCode inPartCode , ResType inTag , Size inSize , const void * inData) { - // 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 - w = wxMax(size.x, 0) ; // WidthDefault( size.x ); - h = wxMax(size.y, 0) ; // HeightDefault( size.y ) ; - - x += MacGetLeftBorderSize() ; - y += MacGetTopBorderSize() ; - w -= MacGetLeftBorderSize() + MacGetRightBorderSize() ; - h -= MacGetTopBorderSize() + MacGetBottomBorderSize() ; - - if ( adjustOrigin ) - AdjustForParentClientOrigin( x , y ) ; - - // this is in window relative coordinate, as this parent may have a border, its physical position is offset by this border - if ( !GetParent()->IsTopLevel() ) - { - x -= GetParent()->MacGetLeftBorderSize() ; - y -= GetParent()->MacGetTopBorderSize() ; - } - - return true ; + return ::SetControlData( m_controlRef , inPartCode , inTag , inSize , inData ); } -// Get window size (not client size) -void wxWindowMac::DoGetSize(int *x, int *y) const +OSStatus wxMacControl::SendEvent( EventRef event , OptionBits inOptions ) { - Rect bounds ; - m_peer->GetRect( &bounds ) ; - - if (x) - *x = bounds.right - bounds.left + MacGetLeftBorderSize() + MacGetRightBorderSize() ; - if (y) - *y = bounds.bottom - bounds.top + MacGetTopBorderSize() + MacGetBottomBorderSize() ; + return SendEventToEventTargetWithOptions( event, + HIObjectGetEventTarget( (HIObjectRef) m_controlRef ), inOptions ); } -// get the position of the bounds of this window in client coordinates of its parent -void wxWindowMac::DoGetPosition(int *x, int *y) const +OSStatus wxMacControl::SendHICommand( HICommand &command , OptionBits inOptions ) { - Rect bounds ; - m_peer->GetRect( &bounds ) ; - - int x1 = bounds.left ; - int y1 = bounds.top ; + wxMacCarbonEvent event( kEventClassCommand , kEventCommandProcess ); - // get the wx window position from the native one - x1 -= MacGetLeftBorderSize() ; - y1 -= MacGetTopBorderSize() ; - - if ( !IsTopLevel() ) - { - wxWindow *parent = GetParent(); - if ( parent ) - { - // we must first adjust it to be in window coordinates of the parent, - // as otherwise it gets lost by the ClientAreaOrigin fix - x1 += parent->MacGetLeftBorderSize() ; - y1 += parent->MacGetTopBorderSize() ; - - // and now to client coordinates - wxPoint pt(parent->GetClientAreaOrigin()); - x1 -= pt.x ; - y1 -= pt.y ; - } - } + event.SetParameter(kEventParamDirectObject,command); - if (x) - *x = x1 ; - if (y) - *y = y1 ; + return SendEvent( event , inOptions ); } -void wxWindowMac::DoScreenToClient(int *x, int *y) const +OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions ) { - WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; - wxCHECK_RET( window , wxT("TopLevel Window missing") ) ; - - Point localwhere = { 0, 0 } ; - - if (x) - localwhere.h = *x ; - if (y) - localwhere.v = *y ; - - wxMacGlobalToLocal( window , &localwhere ) ; + HICommand command; - if (x) - *x = localwhere.h ; - if (y) - *y = localwhere.v ; - - MacRootWindowToWindow( x , y ) ; - - wxPoint origin = GetClientAreaOrigin() ; - if (x) - *x -= origin.x ; - if (y) - *y -= origin.y ; + memset( &command, 0 , sizeof(command) ); + command.commandID = commandID; + return SendHICommand( command , inOptions ); } -void wxWindowMac::DoClientToScreen(int *x, int *y) const +void wxMacControl::PerformClick() { - WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; - wxCHECK_RET( window , wxT("TopLevel window missing") ) ; - - wxPoint origin = GetClientAreaOrigin() ; - if (x) - *x += origin.x ; - if (y) - *y += origin.y ; - - MacWindowToRootWindow( x , y ) ; + HIViewSimulateClick (m_controlRef, kControlButtonPart, 0, NULL ); +} - Point localwhere = { 0, 0 }; - if (x) - localwhere.h = *x ; - if (y) - localwhere.v = *y ; +wxInt32 wxMacControl::GetValue() const +{ + return ::GetControl32BitValue( m_controlRef ); +} - wxMacLocalToGlobal( window, &localwhere ) ; +wxInt32 wxMacControl::GetMaximum() const +{ + return ::GetControl32BitMaximum( m_controlRef ); +} - if (x) - *x = localwhere.h ; - if (y) - *y = localwhere.v ; +wxInt32 wxMacControl::GetMinimum() const +{ + return ::GetControl32BitMinimum( m_controlRef ); } -void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const +void wxMacControl::SetValue( wxInt32 v ) { - wxPoint origin = GetClientAreaOrigin() ; - if (x) - *x += origin.x ; - if (y) - *y += origin.y ; + ::SetControl32BitValue( m_controlRef , v ); +} - MacWindowToRootWindow( x , y ) ; +void wxMacControl::SetMinimum( wxInt32 v ) +{ + ::SetControl32BitMinimum( m_controlRef , v ); } -void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const +void wxMacControl::SetMaximum( wxInt32 v ) { - MacRootWindowToWindow( x , y ) ; + ::SetControl32BitMaximum( m_controlRef , v ); +} - wxPoint origin = GetClientAreaOrigin() ; - if (x) - *x -= origin.x ; - if (y) - *y -= origin.y ; +void wxMacControl::SetValueAndRange( SInt32 value , SInt32 minimum , SInt32 maximum ) +{ + ::SetControl32BitMinimum( m_controlRef , minimum ); + ::SetControl32BitMaximum( m_controlRef , maximum ); + ::SetControl32BitValue( m_controlRef , value ); } -void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const +void wxMacControl::VisibilityChanged(bool WXUNUSED(shown)) { - wxPoint pt ; +} - if (x) - pt.x = *x ; - if (y) - pt.y = *y ; +void wxMacControl::SuperChangedPosition() +{ +} - if ( !IsTopLevel() ) +void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle, bool ignoreBlack ) +{ + m_font = font; +#if wxOSX_USE_CORE_TEXT + if ( UMAGetSystemVersion() >= 0x1050 ) { - wxNonOwnedWindow* top = MacGetTopLevelWindow(); - if (top) + HIViewPartCode part = 0; + HIThemeTextHorizontalFlush flush = kHIThemeTextHorizontalFlushDefault; + if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL ) + flush = kHIThemeTextHorizontalFlushCenter; + else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT ) + flush = kHIThemeTextHorizontalFlushRight; + HIViewSetTextFont( m_controlRef , part , (CTFontRef) font.OSXGetCTFont() ); + HIViewSetTextHorizontalFlush( m_controlRef, part, flush ); + + if ( foreground != *wxBLACK || ignoreBlack == false ) { - pt.x -= MacGetLeftBorderSize() ; - pt.y -= MacGetTopBorderSize() ; - wxMacControl::Convert( &pt , m_peer , top->m_peer ) ; + ControlFontStyleRec fontStyle; + foreground.GetRGBColor( &fontStyle.foreColor ); + fontStyle.flags = kControlUseForeColorMask; + ::SetControlFontStyle( m_controlRef , &fontStyle ); } } +#endif +#if wxOSX_USE_ATSU_TEXT + ControlFontStyleRec fontStyle; + if ( font.MacGetThemeFontID() != kThemeCurrentPortFont ) + { + switch ( font.MacGetThemeFontID() ) + { + case kThemeSmallSystemFont : + fontStyle.font = kControlFontSmallSystemFont; + break; - if (x) - *x = (int) pt.x ; - if (y) - *y = (int) pt.y ; -} + case 109 : // mini font + fontStyle.font = -5; + break; -void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const -{ - int x1 , y1 ; + case kThemeSystemFont : + fontStyle.font = kControlFontBigSystemFont; + break; - if (x) - x1 = *x ; - if (y) - y1 = *y ; + default : + fontStyle.font = kControlFontBigSystemFont; + break; + } - MacWindowToRootWindow( &x1 , &y1 ) ; + fontStyle.flags = kControlUseFontMask; + } + else + { + fontStyle.font = font.MacGetFontNum(); + fontStyle.style = font.MacGetFontStyle(); + fontStyle.size = font.GetPointSize(); + fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask; + } - if (x) - *x = x1 ; - if (y) - *y = y1 ; -} + fontStyle.just = teJustLeft; + fontStyle.flags |= kControlUseJustMask; + if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_CENTER_HORIZONTAL ) + fontStyle.just = teJustCenter; + else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT ) + fontStyle.just = teJustRight; -void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const -{ - wxPoint pt ; - if (x) - pt.x = *x ; - if (y) - pt.y = *y ; + // we only should do this in case of a non-standard color, as otherwise 'disabled' controls + // won't get grayed out by the system anymore - if ( !IsTopLevel() ) + if ( foreground != *wxBLACK || ignoreBlack == false ) { - wxNonOwnedWindow* top = MacGetTopLevelWindow(); - if (top) - { - wxMacControl::Convert( &pt , top->m_peer , m_peer ) ; - pt.x += MacGetLeftBorderSize() ; - pt.y += MacGetTopBorderSize() ; - } + foreground.GetRGBColor( &fontStyle.foreColor ); + fontStyle.flags |= kControlUseForeColorMask; } - if (x) - *x = (int) pt.x ; - if (y) - *y = (int) pt.y ; + ::SetControlFontStyle( m_controlRef , &fontStyle ); +#endif } -void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const +void wxMacControl::SetBackgroundColour( const wxColour &WXUNUSED(col) ) { - int x1 , y1 ; - - if (x) - x1 = *x ; - if (y) - y1 = *y ; - - MacRootWindowToWindow( &x1 , &y1 ) ; +// HITextViewSetBackgroundColor( m_textView , color ); +} - if (x) - *x = x1 ; - if (y) - *y = y1 ; +void wxMacControl::SetRange( SInt32 minimum , SInt32 maximum ) +{ + ::SetControl32BitMinimum( m_controlRef , minimum ); + ::SetControl32BitMaximum( m_controlRef , maximum ); } -void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom ) +short wxMacControl::HandleKey( SInt16 keyCode, SInt16 charCode, EventModifiers modifiers ) { - RgnHandle rgn = NewRgn() ; + return HandleControlKey( m_controlRef , keyCode , charCode , modifiers ); +} - if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) - { - Rect structure, content ; - - GetRegionBounds( rgn , &content ) ; - m_peer->GetRect( &structure ) ; - OffsetRect( &structure, -structure.left , -structure.top ) ; - - left = content.left - structure.left ; - top = content.top - structure.top ; - right = structure.right - content.right ; - bottom = structure.bottom - content.bottom ; - } - else - { - left = top = right = bottom = 0 ; - } - - DisposeRgn( rgn ) ; -} - -wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const -{ - wxSize sizeTotal = size; - - RgnHandle rgn = NewRgn() ; - if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) - { - Rect content, structure ; - GetRegionBounds( rgn , &content ) ; - m_peer->GetRect( &structure ) ; - - // 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) ; - } - - DisposeRgn( rgn ) ; - - sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ; - sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ; - - return sizeTotal; -} - -// Get size *available for subwindows* i.e. excluding menu bar etc. -void wxWindowMac::DoGetClientSize( int *x, int *y ) const -{ - int ww, hh; - - RgnHandle rgn = NewRgn() ; - Rect content ; - if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) - GetRegionBounds( rgn , &content ) ; - else - m_peer->GetRect( &content ) ; - DisposeRgn( rgn ) ; - - ww = content.right - content.left ; - hh = content.bottom - content.top ; - - if (m_hScrollBar && m_hScrollBar->IsShown() ) - hh -= m_hScrollBar->GetSize().y ; - - if (m_vScrollBar && m_vScrollBar->IsShown() ) - ww -= m_vScrollBar->GetSize().x ; - - if (x) - *x = ww; - if (y) - *y = hh; -} - -bool wxWindowMac::SetCursor(const wxCursor& cursor) -{ - if (m_cursor.IsSameAs(cursor)) - return false; - - if (!cursor.IsOk()) - { - if ( ! wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ) ) - return false ; - } - else - { - if ( ! wxWindowBase::SetCursor( cursor ) ) - return false ; - } - - wxASSERT_MSG( m_cursor.Ok(), - wxT("cursor must be valid after call to the base version")); - - wxWindowMac *mouseWin = 0 ; - { - wxNonOwnedWindow *tlw = MacGetTopLevelWindow() ; - WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ; - - ControlPartCode part ; - ControlRef control ; - 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 ( mouseWin == this && !wxIsBusy() ) - m_cursor.MacInstall() ; - - return true ; -} - -#if wxUSE_MENUS -bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) -{ -#ifndef __WXUNIVERSAL__ - menu->SetInvokingWindow((wxWindow*)this); - menu->UpdateUI(); - - if ( x == wxDefaultCoord && y == wxDefaultCoord ) - { - 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) ; - if ( HiWord(menuResult) != 0 ) - { - 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 ) - { - if (item->IsCheckable()) - item->Check( !item->IsChecked() ) ; - - menu->SendEvent( id , item->IsCheckable() ? item->IsChecked() : -1 ) ; - } - } - - menu->MacAfterDisplay( true ) ; - menu->SetInvokingWindow( NULL ); - - return true; -#else - // actually this shouldn't be called, because universal is having its own implementation - return false; -#endif -} -#endif - -// ---------------------------------------------------------------------------- -// tooltips -// ---------------------------------------------------------------------------- - -#if wxUSE_TOOLTIPS - -void wxWindowMac::DoSetToolTip(wxToolTip *tooltip) -{ - wxWindowBase::DoSetToolTip(tooltip); - - if ( m_tooltip ) - m_tooltip->SetWindow(this); -} - -#endif - -void wxWindowMac::MacInvalidateBorders() -{ - if ( m_peer == NULL ) - return ; - - bool vis = IsShownOnScreen() ; - if ( !vis ) - return ; - - int outerBorder = MacGetLeftBorderSize() ; - if ( m_peer->NeedsFocusRect() /* && m_peer->HasFocus() */ ) - outerBorder += 4 ; - - if ( outerBorder == 0 ) - return ; - - // now we know that we have something to do at all - - // as the borders are drawn on the parent we have to properly invalidate all these areas - RgnHandle updateInner , updateOuter; - Rect rect ; - - // this rectangle is in HIViewCoordinates under OSX and in Window Coordinates under Carbon - updateInner = NewRgn() ; - updateOuter = NewRgn() ; - - m_peer->GetRect( &rect ) ; - RectRgn( updateInner, &rect ) ; - InsetRect( &rect , -outerBorder , -outerBorder ) ; - RectRgn( updateOuter, &rect ) ; - DiffRgn( updateOuter, updateInner , updateOuter ) ; - - GetParent()->m_peer->SetNeedsDisplay( updateOuter ) ; - - DisposeRgn( updateOuter ) ; - DisposeRgn( updateInner ) ; -} - -void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) -{ - // this is never called for a toplevel window, so we know we have a parent - int former_x , former_y , former_w, former_h ; - - // Get true coordinates of former position - DoGetPosition( &former_x , &former_y ) ; - DoGetSize( &former_w , &former_h ) ; - - wxWindow *parent = GetParent(); - if ( parent ) - { - wxPoint pt(parent->GetClientAreaOrigin()); - former_x += pt.x ; - former_y += pt.y ; - } - - int actualWidth = width ; - int actualHeight = height ; - int actualX = x; - int actualY = y; - - if ((m_minWidth != -1) && (actualWidth < m_minWidth)) - actualWidth = m_minWidth; - if ((m_minHeight != -1) && (actualHeight < m_minHeight)) - actualHeight = m_minHeight; - if ((m_maxWidth != -1) && (actualWidth > m_maxWidth)) - actualWidth = m_maxWidth; - if ((m_maxHeight != -1) && (actualHeight > m_maxHeight)) - actualHeight = m_maxHeight; - - bool doMove = false, doResize = false ; - - if ( actualX != former_x || actualY != former_y ) - doMove = true ; - - if ( actualWidth != former_w || actualHeight != former_h ) - doResize = true ; - - if ( doMove || doResize ) - { - // as the borders are drawn outside the native control, we adjust now - - wxRect bounds( wxPoint( actualX + MacGetLeftBorderSize() ,actualY + MacGetTopBorderSize() ), - wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) , - actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ; - - Rect r ; - wxMacRectToNative( &bounds , &r ) ; - - if ( !GetParent()->IsTopLevel() ) - wxMacWindowToNative( GetParent() , &r ) ; - - MacInvalidateBorders() ; - - m_cachedClippedRectValid = false ; - m_peer->SetRect( &r ) ; - - wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified - - MacInvalidateBorders() ; - - MacRepositionScrollBars() ; - if ( doMove ) - { - wxPoint point(actualX, actualY); - wxMoveEvent event(point, m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event) ; - } - - if ( doResize ) - { - MacRepositionScrollBars() ; - wxSize size(actualWidth, actualHeight); - wxSizeEvent event(size, m_windowId); - event.SetEventObject(this); - HandleWindowEvent(event); - } - } -} - -wxSize wxWindowMac::DoGetBestSize() const -{ - if ( m_macIsUserPane || IsTopLevel() ) - { - return wxWindowBase::DoGetBestSize() ; - } - else - { - Rect bestsize = { 0 , 0 , 0 , 0 } ; - int bestWidth, bestHeight ; - - m_peer->GetBestRect( &bestsize ) ; - if ( EmptyRect( &bestsize ) ) - { - bestsize.left = - bestsize.top = 0 ; - bestsize.right = - bestsize.bottom = 16 ; - - if ( IsKindOf( CLASSINFO( wxScrollBar ) ) ) - { - bestsize.bottom = 16 ; - } - #if wxUSE_SPINBTN - else if ( IsKindOf( CLASSINFO( wxSpinButton ) ) ) - { - bestsize.bottom = 24 ; - } - #endif - else - { - // return wxWindowBase::DoGetBestSize() ; - } - } - - bestWidth = bestsize.right - bestsize.left + MacGetLeftBorderSize() + - MacGetRightBorderSize(); - bestHeight = bestsize.bottom - bestsize.top + MacGetTopBorderSize() + - MacGetBottomBorderSize(); - if ( bestHeight < 10 ) - bestHeight = 13 ; - - return wxSize(bestWidth, bestHeight); - } -} - -// set the size of the window: if the dimensions are positive, just use them, -// but if any of them is equal to -1, it means that we must find the value for -// it ourselves (unless sizeFlags contains wxSIZE_ALLOW_MINUS_ONE flag, in -// which case -1 is a valid value for x and y) -// -// If sizeFlags contains wxSIZE_AUTO_WIDTH/HEIGHT flags (default), we calculate -// the width/height to best suit our contents, otherwise we reuse the current -// width/height -void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags) -{ - // get the current size and position... - int currentX, currentY; - int currentW, currentH; - - GetPosition(¤tX, ¤tY); - GetSize(¤tW, ¤tH); - - // ... and don't do anything (avoiding flicker) if it's already ok - if ( x == currentX && y == currentY && - width == currentW && height == currentH && ( height != -1 && width != -1 ) ) - { - // TODO: REMOVE - MacRepositionScrollBars() ; // we might have a real position shift - - return; - } - - if ( !(sizeFlags & wxSIZE_ALLOW_MINUS_ONE) ) - { - if ( x == wxDefaultCoord ) - x = currentX; - if ( y == wxDefaultCoord ) - y = currentY; - } - - AdjustForParentClientOrigin( x, y, sizeFlags ); - - wxSize size = wxDefaultSize; - if ( width == wxDefaultCoord ) - { - if ( sizeFlags & wxSIZE_AUTO_WIDTH ) - { - size = DoGetBestSize(); - width = size.x; - } - else - { - // just take the current one - width = currentW; - } - } - - if ( height == wxDefaultCoord ) - { - if ( sizeFlags & wxSIZE_AUTO_HEIGHT ) - { - if ( size.x == wxDefaultCoord ) - size = DoGetBestSize(); - // else: already called DoGetBestSize() above - - height = size.y; - } - else - { - // just take the current one - height = currentH; - } - } - - DoMoveWindow( x, y, width, height ); -} - -wxPoint wxWindowMac::GetClientAreaOrigin() const -{ - RgnHandle rgn = NewRgn() ; - Rect content ; - if ( m_peer->GetRegion( kControlContentMetaPart , rgn ) == noErr ) - { - GetRegionBounds( rgn , &content ) ; - } - else - { - content.left = - content.top = 0 ; - } - - DisposeRgn( rgn ) ; - - return wxPoint( content.left + MacGetLeftBorderSize() , content.top + MacGetTopBorderSize() ); -} - -void wxWindowMac::DoSetClientSize(int clientwidth, int clientheight) -{ - if ( clientwidth != wxDefaultCoord || clientheight != wxDefaultCoord ) - { - int currentclientwidth , currentclientheight ; - int currentwidth , currentheight ; - - GetClientSize( ¤tclientwidth , ¤tclientheight ) ; - GetSize( ¤twidth , ¤theight ) ; - - DoSetSize( wxDefaultCoord , wxDefaultCoord , currentwidth + clientwidth - currentclientwidth , - currentheight + clientheight - currentclientheight , wxSIZE_USE_EXISTING ) ; - } -} - -void wxWindowMac::SetLabel(const wxString& title) -{ - m_label = title ; - - if ( m_peer && m_peer->Ok() ) - m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; - - // do not trigger refreshes upon invisible and possible partly created objects - if ( IsShownOnScreen() ) - Refresh() ; -} - -wxString wxWindowMac::GetLabel() const -{ - return m_label ; -} - -bool wxWindowMac::Show(bool show) -{ - if ( !wxWindowBase::Show(show) ) - return false; - - if ( m_peer ) - m_peer->SetVisibility( show , true ) ; - - return true; -} - -void wxWindowMac::DoEnable(bool enable) -{ - m_peer->Enable( enable ) ; -} - -// -// status change notifications -// - -void wxWindowMac::MacVisibilityChanged() -{ -} - -void wxWindowMac::MacHiliteChanged() -{ -} - -void wxWindowMac::MacEnabledStateChanged() -{ - OnEnabled( m_peer->IsEnabled() ); -} - -// -// status queries on the inherited window's state -// - -bool wxWindowMac::MacIsReallyEnabled() -{ - return m_peer->IsEnabled() ; -} - -bool wxWindowMac::MacIsReallyHilited() -{ - return m_peer->IsActive(); -} - -void wxWindowMac::MacFlashInvalidAreas() -{ -#if TARGET_API_MAC_OSX - HIViewFlashDirtyArea( (WindowRef) MacGetTopLevelWindowRef() ) ; -#endif -} - -int wxWindowMac::GetCharHeight() const -{ - wxClientDC dc( (wxWindowMac*)this ) ; - - return dc.GetCharHeight() ; -} - -int wxWindowMac::GetCharWidth() const -{ - wxClientDC dc( (wxWindowMac*)this ) ; - - return dc.GetCharWidth() ; -} - -void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, - int *descent, int *externalLeading, const wxFont *theFont ) const -{ - const wxFont *fontToUse = theFont; - wxFont tempFont; - if ( !fontToUse ) - { - tempFont = GetFont(); - fontToUse = &tempFont; - } - - wxClientDC dc( (wxWindowMac*) this ) ; - wxCoord lx,ly,ld,le ; - dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ; - if ( externalLeading ) - *externalLeading = le ; - if ( descent ) - *descent = ld ; - if ( x ) - *x = lx ; - if ( y ) - *y = ly ; -} - -/* - * Rect is given in client coordinates, for further reading, read wxTopLevelWindowMac::InvalidateRect - * we always intersect with the entire window, not only with the client area - */ - -void wxWindowMac::Refresh(bool WXUNUSED(eraseBack), const wxRect *rect) -{ - if ( m_peer == NULL ) - return ; - - if ( !IsShownOnScreen() ) - return ; - - if ( rect ) - { - Rect r ; - - wxMacRectToNative( rect , &r ) ; - m_peer->SetNeedsDisplay( &r ) ; - } - else - { - m_peer->SetNeedsDisplay() ; - } -} - -void wxWindowMac::DoFreeze() -{ -#if TARGET_API_MAC_OSX - if ( m_peer && m_peer->Ok() ) - m_peer->SetDrawingEnabled( false ) ; -#endif -} - -void wxWindowMac::DoThaw() -{ -#if TARGET_API_MAC_OSX - if ( m_peer && m_peer->Ok() ) - { - m_peer->SetDrawingEnabled( true ) ; - m_peer->InvalidateWithChildren() ; - } -#endif -} - -wxWindowMac *wxGetActiveWindow() -{ - // actually this is a windows-only concept - return NULL; -} - -// Coordinates relative to the window -void wxWindowMac::WarpPointer(int WXUNUSED(x_pos), int WXUNUSED(y_pos)) -{ - // We really don't move the mouse programmatically under Mac. -} - -void wxWindowMac::OnEraseBackground(wxEraseEvent& event) -{ - if ( MacGetTopLevelWindow() == NULL ) - return ; -/* -#if TARGET_API_MAC_OSX - if ( !m_backgroundColour.Ok() || GetBackgroundStyle() == wxBG_STYLE_TRANSPARENT ) - { - } - else -#endif -*/ - if ( GetBackgroundStyle() == wxBG_STYLE_COLOUR ) - { - event.GetDC()->Clear() ; - } - else if ( GetBackgroundStyle() == wxBG_STYLE_CUSTOM ) - { - // don't skip the event here, custom background means that the app - // is drawing it itself in its OnPaint(), so don't draw it at all - // now to avoid flicker - } - else - { - event.Skip() ; - } -} - -void wxWindowMac::OnNcPaint( wxNcPaintEvent& event ) -{ - event.Skip() ; -} - -int wxWindowMac::GetScrollPos(int orient) const -{ - if ( orient == wxHORIZONTAL ) - { - if ( m_hScrollBar ) - return m_hScrollBar->GetThumbPosition() ; - } - else - { - if ( m_vScrollBar ) - return m_vScrollBar->GetThumbPosition() ; - } - - return 0; -} - -// This now returns the whole range, not just the number -// of positions that we can scroll. -int wxWindowMac::GetScrollRange(int orient) const -{ - if ( orient == wxHORIZONTAL ) - { - if ( m_hScrollBar ) - return m_hScrollBar->GetRange() ; - } - else - { - if ( m_vScrollBar ) - return m_vScrollBar->GetRange() ; - } - - return 0; -} - -int wxWindowMac::GetScrollThumb(int orient) const -{ - if ( orient == wxHORIZONTAL ) - { - if ( m_hScrollBar ) - return m_hScrollBar->GetThumbSize() ; - } - else - { - if ( m_vScrollBar ) - return m_vScrollBar->GetThumbSize() ; - } - - return 0; -} - -void wxWindowMac::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh)) -{ - if ( orient == wxHORIZONTAL ) - { - if ( m_hScrollBar ) - m_hScrollBar->SetThumbPosition( pos ) ; - } - else - { - if ( m_vScrollBar ) - m_vScrollBar->SetThumbPosition( pos ) ; - } -} - -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::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, (CGFloat) 1.0, (CGFloat)1.0 ,(CGFloat) 1.0 , (CGFloat)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() ; - - // back to the surrounding frame rectangle - m_peer->GetRect( &rect ) ; - InsetRect( &rect, -1 , -1 ) ; - - { - CGRect cgrect = CGRectMake( rect.left , rect.top , rect.right - rect.left , - rect.bottom - rect.top ) ; - - HIThemeFrameDrawInfo info ; - memset( &info, 0 , sizeof(info) ) ; - - info.version = 0 ; - info.kind = 0 ; - info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; - info.isFocused = hasFocus ; - - CGContextRef cgContext = (CGContextRef) GetParent()->MacGetCGContextRef() ; - wxASSERT( cgContext ) ; - - if ( HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER) ) - { - info.kind = kHIThemeFrameTextFieldSquare ; - HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; - } - else if ( HasFlag(wxSIMPLE_BORDER) ) - { - info.kind = kHIThemeFrameListBox ; - HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; - } - else if ( hasFocus ) - { - 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 ( MacHasScrollBarCorner() ) - { - 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 ; - memset( &info, 0, sizeof(info) ) ; - info.version = 0 ; - info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; - info.kind = kHIThemeGrowBoxKindNone ; - // contrary to the docs ...SizeSmall does not work - info.size = kHIThemeGrowBoxSizeNormal ; - info.direction = 0 ; - HIThemeDrawGrowBox( &cgpoint , &info , cgContext , kHIThemeOrientationNormal ) ; - } -#endif - } -} - -void wxWindowMac::RemoveChild( wxWindowBase *child ) -{ - if ( child == m_hScrollBar ) - m_hScrollBar = NULL ; - if ( child == m_vScrollBar ) - m_vScrollBar = NULL ; - - wxWindowBase::RemoveChild( child ) ; -} - -void wxWindowMac::DoUpdateScrollbarVisibility() -{ - bool triggerSizeEvent = false; - - if ( m_hScrollBar ) - { - bool showHScrollBar = m_hScrollBarAlwaysShown || m_hScrollBar->IsNeeded(); - - if ( m_hScrollBar->IsShown() != showHScrollBar ) - { - m_hScrollBar->Show( showHScrollBar ); - triggerSizeEvent = true; - } - } - - if ( m_vScrollBar) - { - bool showVScrollBar = m_vScrollBarAlwaysShown || m_vScrollBar->IsNeeded(); - - if ( m_vScrollBar->IsShown() != showVScrollBar ) - { - m_vScrollBar->Show( showVScrollBar ) ; - triggerSizeEvent = true; - } - } - - MacRepositionScrollBars() ; - if ( triggerSizeEvent ) - { - wxSizeEvent event(GetSize(), m_windowId); - event.SetEventObject(this); - HandleWindowEvent(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 -void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) -{ - if ( dx == 0 && dy == 0 ) - return ; - - int width , height ; - GetClientSize( &width , &height ) ; - - { - // 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() , width , height ) ; - if ( rect ) - scrollrect.Intersect( *rect ) ; - - if ( m_peer->GetNeedsDisplay() ) - { - // 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 - HIViewRender(m_peer->GetControlRef()) ; -#endif - } - - // as the native control might be not a 0/0 wx window coordinates, we have to offset - scrollrect.Offset( -MacGetLeftBorderSize() , -MacGetTopBorderSize() ) ; - m_peer->ScrollRect( &scrollrect , dx , dy ) ; - -#if 0 - // this would be the preferred version for fast drawing controls - HIViewRender(m_peer->GetControlRef()) ; -#endif - } - - wxWindowMac *child; - int x, y, w, h; - for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext()) - { - child = node->GetData(); - if (child == NULL) - continue; - if (child == m_vScrollBar) - continue; - if (child == m_hScrollBar) - continue; - if (child->IsTopLevel()) - continue; - - child->GetPosition( &x, &y ); - child->GetSize( &w, &h ); - if (rect) - { - wxRect rc( x, y, w, h ); - if (rect->Intersects( rc )) - child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE ); - } - else - { - child->SetSize( x + dx, y + dy, w, h, wxSIZE_AUTO|wxSIZE_ALLOW_MINUS_ONE ); - } - } -} - -void wxWindowMac::MacOnScroll( wxScrollEvent &event ) -{ - if ( event.GetEventObject() == m_vScrollBar || event.GetEventObject() == m_hScrollBar ) - { - wxScrollWinEvent wevent; - wevent.SetPosition(event.GetPosition()); - wevent.SetOrientation(event.GetOrientation()); - wevent.SetEventObject(this); - - if (event.GetEventType() == wxEVT_SCROLL_TOP) - wevent.SetEventType( wxEVT_SCROLLWIN_TOP ); - else if (event.GetEventType() == wxEVT_SCROLL_BOTTOM) - wevent.SetEventType( wxEVT_SCROLLWIN_BOTTOM ); - else if (event.GetEventType() == wxEVT_SCROLL_LINEUP) - wevent.SetEventType( wxEVT_SCROLLWIN_LINEUP ); - else if (event.GetEventType() == wxEVT_SCROLL_LINEDOWN) - wevent.SetEventType( wxEVT_SCROLLWIN_LINEDOWN ); - else if (event.GetEventType() == wxEVT_SCROLL_PAGEUP) - wevent.SetEventType( wxEVT_SCROLLWIN_PAGEUP ); - else if (event.GetEventType() == wxEVT_SCROLL_PAGEDOWN) - wevent.SetEventType( wxEVT_SCROLLWIN_PAGEDOWN ); - else if (event.GetEventType() == wxEVT_SCROLL_THUMBTRACK) - wevent.SetEventType( wxEVT_SCROLLWIN_THUMBTRACK ); - else if (event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE) - wevent.SetEventType( wxEVT_SCROLLWIN_THUMBRELEASE ); - - HandleWindowEvent(wevent); - } -} - -// Get the window with the focus -wxWindowMac *wxWindowBase::DoFindFocus() -{ - ControlRef control ; - GetKeyboardFocus( GetUserFocusWindow() , &control ) ; - return wxFindControlFromMacControl( control ) ; -} - -void wxWindowMac::OnInternalIdle() +void wxMacControl::SetActionProc( ControlActionUPP actionProc ) { - // This calls the UI-update mechanism (querying windows for - // menu/toolbar/control state information) - if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); + SetControlAction( m_controlRef , actionProc ); } -// Raise the window to the top of the Z order -void wxWindowMac::Raise() +SInt32 wxMacControl::GetViewSize() const { - m_peer->SetZOrder( true , NULL ) ; + return GetControlViewSize( m_controlRef ); } -// Lower the window to the bottom of the Z order -void wxWindowMac::Lower() +bool wxMacControl::IsVisible() const { - m_peer->SetZOrder( false , NULL ) ; + return IsControlVisible( m_controlRef ); } -// static wxWindow *gs_lastWhich = NULL; - -bool wxWindowMac::MacSetupCursor( const wxPoint& pt ) -{ - // first trigger a set cursor event - - wxPoint clientorigin = GetClientAreaOrigin() ; - wxSize clientsize = GetClientSize() ; - wxCursor cursor ; - if ( wxRect2DInt( clientorigin.x , clientorigin.y , clientsize.x , clientsize.y ).Contains( wxPoint2DInt( pt ) ) ) - { - wxSetCursorEvent event( pt.x , pt.y ); - - bool processedEvtSetCursor = HandleWindowEvent(event); - if ( processedEvtSetCursor && event.HasCursor() ) - { - cursor = event.GetCursor() ; - } - else - { - // the test for processedEvtSetCursor is here to prevent using m_cursor - // if the user code caught EVT_SET_CURSOR() and returned nothing from - // it - this is a way to say that our cursor shouldn't be used for this - // point - if ( !processedEvtSetCursor && m_cursor.Ok() ) - cursor = m_cursor ; - - if ( !wxIsBusy() && !GetParent() ) - cursor = *wxSTANDARD_CURSOR ; - } - - if ( cursor.Ok() ) - cursor.MacInstall() ; - } - - return cursor.Ok() ; -} - -wxString wxWindowMac::MacGetToolTipString( wxPoint &WXUNUSED(pt) ) -{ -#if wxUSE_TOOLTIPS - if ( m_tooltip ) - return m_tooltip->GetTip() ; -#endif - - return wxEmptyString ; -} - -void wxWindowMac::ClearBackground() -{ - Refresh() ; - Update() ; -} - -void wxWindowMac::Update() -{ - wxNonOwnedWindow* top = MacGetTopLevelWindow(); - if (top) - top->MacPerformUpdates() ; -} - -wxNonOwnedWindow* wxWindowMac::MacGetTopLevelWindow() const -{ - wxNonOwnedWindow* win = NULL ; - WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; - if ( window ) - win = wxFindWinFromMacWindow( window ) ; - - return win ; -} - -const wxRect& wxWindowMac::MacGetClippedClientRect() const +void wxMacControl::SetVisibility( bool visible ) { - MacUpdateClippedRects() ; - - return m_cachedClippedClientRect ; + SetControlVisibility( m_controlRef , visible, true ); } -const wxRect& wxWindowMac::MacGetClippedRect() const +bool wxMacControl::IsEnabled() const { - MacUpdateClippedRects() ; - - return m_cachedClippedRect ; + return IsControlEnabled( m_controlRef ); } -const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const +bool wxMacControl::IsActive() const { - MacUpdateClippedRects() ; - - return m_cachedClippedRectWithOuterStructure ; + return IsControlActive( m_controlRef ); } -const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures ) +void wxMacControl::Enable( bool enable ) { - static wxRegion emptyrgn ; - - if ( !m_isBeingDeleted && IsShownOnScreen() ) - { - MacUpdateClippedRects() ; - if ( includeOuterStructures ) - return m_cachedClippedRegionWithOuterStructure ; - else - return m_cachedClippedRegion ; - } + if ( enable ) + EnableControl( m_controlRef ); else - { - return emptyrgn ; - } + DisableControl( m_controlRef ); } -void wxWindowMac::MacUpdateClippedRects() const +void wxMacControl::SetDrawingEnabled( bool enable ) { - if ( m_cachedClippedRectValid ) - return ; - - // includeOuterStructures is true if we try to draw somthing like a focus ring etc. - // also a window dc uses this, in this case we only clip in the hierarchy for hard - // borders like a scrollwindow, splitter etc otherwise we end up in a paranoia having - // to add focus borders everywhere - - Rect r, rIncludingOuterStructures ; - - m_peer->GetRect( &r ) ; - r.left -= MacGetLeftBorderSize() ; - r.top -= MacGetTopBorderSize() ; - r.bottom += MacGetBottomBorderSize() ; - r.right += MacGetRightBorderSize() ; - - r.right -= r.left ; - r.bottom -= r.top ; - r.left = 0 ; - r.top = 0 ; - - rIncludingOuterStructures = r ; - InsetRect( &rIncludingOuterStructures , -4 , -4 ) ; - - wxRect cl = GetClientRect() ; - Rect rClient = { cl.y , cl.x , cl.y + cl.height , cl.x + cl.width } ; - - int x , y ; - wxSize size ; - const wxWindow* child = this ; - const wxWindow* parent = NULL ; - - while ( !child->IsTopLevel() && ( parent = child->GetParent() ) != NULL ) - { - if ( parent->MacIsChildOfClientArea(child) ) - { - size = parent->GetClientSize() ; - wxPoint origin = parent->GetClientAreaOrigin() ; - x = origin.x ; - y = origin.y ; - } - else - { - // this will be true for scrollbars, toolbars etc. - size = parent->GetSize() ; - y = parent->MacGetTopBorderSize() ; - x = parent->MacGetLeftBorderSize() ; - size.x -= parent->MacGetLeftBorderSize() + parent->MacGetRightBorderSize() ; - size.y -= parent->MacGetTopBorderSize() + parent->MacGetBottomBorderSize() ; - } - - parent->MacWindowToRootWindow( &x, &y ) ; - MacRootWindowToWindow( &x , &y ) ; - - Rect rparent = { y , x , y + size.y , x + size.x } ; - - // the wxwindow and client rects will always be clipped - SectRect( &r , &rparent , &r ) ; - SectRect( &rClient , &rparent , &rClient ) ; - - // the structure only at 'hard' borders - if ( parent->MacClipChildren() || - ( parent->GetParent() && parent->GetParent()->MacClipGrandChildren() ) ) - { - SectRect( &rIncludingOuterStructures , &rparent , &rIncludingOuterStructures ) ; - } - - child = parent ; - } - - m_cachedClippedRect = wxRect( r.left , r.top , r.right - r.left , r.bottom - r.top ) ; - m_cachedClippedClientRect = wxRect( rClient.left , rClient.top , - rClient.right - rClient.left , rClient.bottom - rClient.top ) ; - m_cachedClippedRectWithOuterStructure = wxRect( - rIncludingOuterStructures.left , rIncludingOuterStructures.top , - rIncludingOuterStructures.right - rIncludingOuterStructures.left , - rIncludingOuterStructures.bottom - rIncludingOuterStructures.top ) ; - - m_cachedClippedRegionWithOuterStructure = wxRegion( m_cachedClippedRectWithOuterStructure ) ; - m_cachedClippedRegion = wxRegion( m_cachedClippedRect ) ; - m_cachedClippedClientRegion = wxRegion( m_cachedClippedClientRect ) ; - - m_cachedClippedRectValid = true ; + HIViewSetDrawingEnabled( m_controlRef , enable ); } -/* - This function must not change the updatergn ! - */ -bool wxWindowMac::MacDoRedraw( void* updatergnr , long time ) +void wxMacControl::GetRectInWindowCoords( Rect *r ) { - bool handled = false ; - Rect updatebounds ; - RgnHandle updatergn = (RgnHandle) updatergnr ; - GetRegionBounds( updatergn , &updatebounds ) ; - - // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ; - - if ( !EmptyRgn(updatergn) ) - { - RgnHandle newupdate = NewRgn() ; - wxSize point = GetClientSize() ; - wxPoint origin = GetClientAreaOrigin() ; - SetRectRgn( newupdate , origin.x , origin.y , origin.x + point.x , origin.y + point.y ) ; - SectRgn( newupdate , updatergn , newupdate ) ; - - // first send an erase event to the entire update area - { - // for the toplevel window this really is the entire area - // for all the others only their client area, otherwise they - // might be drawing with full alpha and eg put blue into - // the grow-box area of a scrolled window (scroll sample) - wxDC* dc = new wxWindowDC(this); - if ( IsTopLevel() ) - dc->SetClippingRegion(wxRegion(HIShapeCreateWithQDRgn(updatergn))); - else - dc->SetClippingRegion(wxRegion(HIShapeCreateWithQDRgn(newupdate))); - - wxEraseEvent eevent( GetId(), dc ); - eevent.SetEventObject( this ); - HandleWindowEvent( eevent ); - 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 = wxRegion(HIShapeCreateWithQDRgn(newupdate)) ; - DisposeRgn( newupdate ) ; - - if ( !m_updateRegion.Empty() ) - { - // paint the window itself - - wxPaintEvent event; - event.SetTimestamp(time); - event.SetEventObject(this); - HandleWindowEvent(event); - handled = true ; - } - - // now we cannot rely on having its borders drawn by a window itself, as it does not - // get the updateRgn wide enough to always do so, so we do it from the parent - // this would also be the place to draw any custom backgrounds for native controls - // in Composited windowing - wxPoint clientOrigin = GetClientAreaOrigin() ; - - wxWindowMac *child; - int x, y, w, h; - for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext()) - { - child = node->GetData(); - if (child == NULL) - continue; - if (child == m_vScrollBar) - continue; - if (child == m_hScrollBar) - continue; - if (child->IsTopLevel()) - continue; - if (!child->IsShown()) - continue; - - // only draw those in the update region (add a safety margin of 10 pixels for shadow effects - - child->GetPosition( &x, &y ); - child->GetSize( &w, &h ); - Rect childRect = { y , x , y + h , x + w } ; - OffsetRect( &childRect , clientOrigin.x , clientOrigin.y ) ; - InsetRect( &childRect , -10 , -10) ; - - if ( RectInRgn( &childRect , updatergn ) ) - { - // paint custom borders - wxNcPaintEvent eventNc( child->GetId() ); - eventNc.SetEventObject( child ); - if ( !child->HandleWindowEvent( eventNc ) ) - { - child->MacPaintBorders(0, 0) ; - } - } - } - } - - return handled ; -} + GetControlBounds( m_controlRef , r ) ; + WindowRef tlwref = GetControlOwner( m_controlRef ) ; -WXWindow wxWindowMac::MacGetTopLevelWindowRef() const -{ - wxWindowMac *iter = (wxWindowMac*)this ; - - while ( iter ) + wxNonOwnedWindow* tlwwx = wxNonOwnedWindow::GetFromWXWindow( (WXWindow) tlwref ) ; + if ( tlwwx != NULL ) { - if ( iter->IsTopLevel() ) - { - wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow); - if ( toplevel ) - return toplevel->MacGetWindowRef(); -#if wxUSE_POPUPWIN - wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow); - if ( popupwin ) - return popupwin->MacGetWindowRef(); -#endif - } - iter = iter->GetParent() ; + ControlRef rootControl = tlwwx->GetPeer()->GetControlRef() ; + HIPoint hiPoint = CGPointMake( 0 , 0 ) ; + HIViewConvertPoint( &hiPoint , HIViewGetSuperview(m_controlRef) , rootControl ) ; + OffsetRect( r , (short) hiPoint.x , (short) hiPoint.y ) ; } - - return NULL ; } -bool wxWindowMac::MacHasScrollBarCorner() const +void wxMacControl::GetBestRect( wxRect *rect ) 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; + short baselineoffset; + Rect r = {0,0,0,0}; - 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 ; - } + GetBestControlRect( m_controlRef , &r , &baselineoffset ); + *rect = wxRect( r.left, r.top, r.right - r.left, r.bottom-r.top ); } -void wxWindowMac::MacCreateScrollBars( long style ) +void wxMacControl::GetBestRect( Rect *r ) const { - wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ; - - if ( style & ( wxVSCROLL | wxHSCROLL ) ) - { - int scrlsize = MAC_SCROLLBAR_SIZE ; - if ( GetWindowVariant() == wxWINDOW_VARIANT_SMALL || GetWindowVariant() == wxWINDOW_VARIANT_MINI ) - { - scrlsize = MAC_SMALL_SCROLLBAR_SIZE ; - } - - 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) ; - - // 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((wxWindow*)this, wxID_ANY, vPoint, vSize , wxVERTICAL); - m_vScrollBar->SetMinSize( wxDefaultSize ); - } - - if ( style & wxHSCROLL ) - { - 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 - // we might have a real position shift - MacRepositionScrollBars() ; + short baselineoffset; + GetBestControlRect( m_controlRef , r , &baselineoffset ); } -bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const +void wxMacControl::SetLabel( const wxString &title , wxFontEncoding encoding) { - bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar))); - - return result ; + SetControlTitleWithCFString( m_controlRef , wxCFStringRef( title , encoding ) ); } -void wxWindowMac::MacRepositionScrollBars() +void wxMacControl::GetFeatures( UInt32 * features ) { - if ( !m_hScrollBar && !m_vScrollBar ) - return ; - - int scrlsize = m_hScrollBar ? m_hScrollBar->GetSize().y : ( m_vScrollBar ? m_vScrollBar->GetSize().x : MAC_SCROLLBAR_SIZE ) ; - int adjust = MacHasScrollBarCorner() ? scrlsize - 1 : 0 ; - - // get real client area - int width, height ; - GetSize( &width , &height ); - - width -= MacGetLeftBorderSize() + MacGetRightBorderSize(); - height -= MacGetTopBorderSize() + MacGetBottomBorderSize(); - - wxPoint vPoint( width - scrlsize, 0 ) ; - wxSize vSize( scrlsize, height - adjust ) ; - wxPoint hPoint( 0 , height - scrlsize ) ; - wxSize hSize( width - adjust, scrlsize ) ; - -#if 0 - int x = 0, y = 0, w, h ; - GetSize( &w , &h ) ; - - MacClientToRootWindow( &x , &y ) ; - MacClientToRootWindow( &w , &h ) ; - - wxWindowMac *iter = (wxWindowMac*)this ; - - int totW = 10000 , totH = 10000; - while ( iter ) - { - if ( iter->IsTopLevel() ) - { - iter->GetSize( &totW , &totH ) ; - break ; - } - - iter = iter->GetParent() ; - } - - if ( x == 0 ) - { - hPoint.x = -1 ; - hSize.x += 1 ; - } - if ( y == 0 ) - { - vPoint.y = -1 ; - vSize.y += 1 ; - } - - if ( w - x >= totW ) - { - hSize.x += 1 ; - vPoint.x += 1 ; - } - if ( h - y >= totH ) - { - vSize.y += 1 ; - hPoint.y += 1 ; - } -#endif - - if ( m_vScrollBar ) - m_vScrollBar->SetSize( vPoint.x , vPoint.y, vSize.x, vSize.y , wxSIZE_ALLOW_MINUS_ONE ); - if ( m_hScrollBar ) - m_hScrollBar->SetSize( hPoint.x , hPoint.y, hSize.x, hSize.y, wxSIZE_ALLOW_MINUS_ONE ); + GetControlFeatures( m_controlRef , features ); } -bool wxWindowMac::AcceptsFocus() const +void wxMacControl::PulseGauge() { - return MacCanFocus() && wxWindowBase::AcceptsFocus(); } -void wxWindowMac::MacSuperChangedPosition() +// SetNeedsDisplay would not invalidate the children +static void InvalidateControlAndChildren( HIViewRef control ) { - // only window-absolute structures have to be moved i.e. controls - - m_cachedClippedRectValid = false ; - - wxWindowMac *child; - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) - { - child = node->GetData(); - child->MacSuperChangedPosition() ; - - node = node->GetNext(); - } -} + HIViewSetNeedsDisplay( control , true ); + UInt16 childrenCount = 0; + OSStatus err = CountSubControls( control , &childrenCount ); + if ( err == errControlIsNotEmbedder ) + return; -void wxWindowMac::MacTopLevelWindowChangedPosition() -{ - // only screen-absolute structures have to be moved i.e. glcanvas + wxASSERT_MSG( err == noErr , wxT("Unexpected error when accessing subcontrols") ); - wxWindowMac *child; - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) + for ( UInt16 i = childrenCount; i >=1; --i ) { - child = node->GetData(); - child->MacTopLevelWindowChangedPosition() ; - - node = node->GetNext(); - } -} - -long wxWindowMac::MacGetLeftBorderSize() const -{ - if ( IsTopLevel() ) - return 0 ; + HIViewRef child; - SInt32 border = 0 ; + err = GetIndexedSubControl( control , i , & child ); + if ( err == errControlIsNotEmbedder ) + return; - 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 ; + InvalidateControlAndChildren( child ); } - else if (HasFlag(wxSIMPLE_BORDER)) - { - // this metric is only the 'outset' outside the simple frame rect - GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; - border += 1 ; - } - - return border ; -} - -long wxWindowMac::MacGetRightBorderSize() const -{ - // they are all symmetric in mac themes - return MacGetLeftBorderSize() ; -} - -long wxWindowMac::MacGetTopBorderSize() const -{ - // they are all symmetric in mac themes - return MacGetLeftBorderSize() ; -} - -long wxWindowMac::MacGetBottomBorderSize() const -{ - // they are all symmetric in mac themes - return MacGetLeftBorderSize() ; } -long wxWindowMac::MacRemoveBordersFromStyle( long style ) +void wxMacControl::InvalidateWithChildren() { - return style & ~wxBORDER_MASK ; + InvalidateControlAndChildren( m_controlRef ); } -// Find the wxWindowMac at the current mouse position, returning the mouse -// position. -wxWindowMac * wxFindWindowAtPointer( wxPoint& pt ) -{ - pt = wxGetMousePosition(); - wxWindowMac* found = wxFindWindowAtPoint(pt); - - return found; -} +OSType wxMacCreator = 'WXMC'; +OSType wxMacControlProperty = 'MCCT'; -// Get the current mouse position. -wxPoint wxGetMousePosition() +void wxMacControl::SetReferenceInNativeControl() { - int x, y; - - wxGetMousePosition( &x, &y ); - - return wxPoint(x, y); + void * data = this; + verify_noerr( SetControlProperty ( m_controlRef , + wxMacCreator,wxMacControlProperty, sizeof(data), &data ) ); } -void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) +wxMacControl* wxMacControl::GetReferenceFromNativeControl(ControlRef control) { - if ( event.GetEventType() == wxEVT_RIGHT_DOWN ) - { - // copied from wxGTK : CS - // VZ: shouldn't we move this to base class then? - - // generate a "context menu" event: this is similar to wxEVT_RIGHT_DOWN - // except that: - // - // (a) it's a command event and so is propagated to the parent - // (b) under MSW it can be generated from kbd too - // (c) it uses screen coords (because of (a)) - wxContextMenuEvent evtCtx(wxEVT_CONTEXT_MENU, - this->GetId(), - this->ClientToScreen(event.GetPosition())); - evtCtx.SetEventObject(this); - if ( ! HandleWindowEvent(evtCtx) ) - event.Skip() ; - } - else + wxMacControl* ctl = NULL; + ByteCount actualSize; + if ( GetControlProperty( control ,wxMacCreator,wxMacControlProperty, sizeof(ctl) , + &actualSize , &ctl ) == noErr ) { - event.Skip() ; + return ctl; } + return NULL; } -void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) ) +wxBitmap wxMacControl::GetBitmap() const { - // for native controls: call their native paint method - if ( !MacIsUserPane() || ( IsTopLevel() && GetBackgroundStyle() == wxBG_STYLE_SYSTEM ) ) - { - if ( wxTheApp->MacGetCurrentEvent() != NULL && wxTheApp->MacGetCurrentEventHandlerCallRef() != NULL - && GetBackgroundStyle() != wxBG_STYLE_TRANSPARENT ) - CallNextEventHandler( - (EventHandlerCallRef)wxTheApp->MacGetCurrentEventHandlerCallRef() , - (EventRef) wxTheApp->MacGetCurrentEvent() ) ; - } + return wxNullBitmap; } -void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control), - wxInt16 WXUNUSED(controlpart), - bool WXUNUSED(mouseStillDown)) +void wxMacControl::SetBitmap( const wxBitmap& WXUNUSED(bmp) ) { + // implemented in the respective subclasses } -Rect wxMacGetBoundsForControl( wxWindow* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin ) +void wxMacControl::SetBitmapPosition( wxDirection WXUNUSED(dir) ) { - int x, y, w, h ; - - window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ; - Rect bounds = { y, x, y + h, x + w }; - - return bounds ; + // implemented in the same subclasses that implement SetBitmap() } -wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) +void wxMacControl::SetScrollThumb( wxInt32 WXUNUSED(pos), wxInt32 WXUNUSED(viewsize) ) { - return eventNotHandledErr ; + // implemented in respective subclass } -bool wxWindowMac::Reparent(wxWindowBase *newParentBase) -{ - wxWindowMac *newParent = (wxWindowMac *)newParentBase; - if ( !wxWindowBase::Reparent(newParent) ) - return false; - - // copied from MacPostControlCreate - ControlRef container = (ControlRef) GetParent()->GetHandle() ; - - wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; - - ::EmbedControl( m_peer->GetControlRef() , container ) ; - - return true; -} +// +// Tab Control +// -bool wxWindowMac::SetTransparent(wxByte alpha) +OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable ) { - SetBackgroundStyle(wxBG_STYLE_TRANSPARENT); - - if ( alpha != m_macAlpha ) - { - m_macAlpha = alpha ; - Refresh() ; - } - return true ; + return ::SetTabEnabled( m_controlRef , tabNo , enable ); } -bool wxWindowMac::CanSetTransparent() -{ - return true ; -} -wxByte wxWindowMac::GetTransparent() const -{ - return m_macAlpha ; -} +// Control Factory -bool wxWindowMac::IsShownOnScreen() const +wxWidgetImplType* wxWidgetImpl::CreateContentView( wxNonOwnedWindow* now ) { -#if TARGET_API_MAC_OSX - if ( m_peer && m_peer->Ok() ) - { - bool peerVis = m_peer->IsVisible(); - bool wxVis = wxWindowBase::IsShownOnScreen(); - if( peerVis != wxVis ) - { - // CS : put a breakpoint here to investigate differences - // between native an wx visibilities - // the only place where I've encountered them until now - // are the hiding/showing sequences where the vis-changed event is - // first sent to the innermost control, while wx does things - // from the outmost control - wxVis = wxWindowBase::IsShownOnScreen(); - return wxVis; - } + // There is a bug in 10.2.X for ::GetRootControl returning the window view instead of + // the content view, so we have to retrieve it explicitly - return m_peer->IsVisible(); + wxMacControl* contentview = new wxMacControl(now , true /*isRootControl*/); + HIViewFindByID( HIViewGetRoot( (WindowRef) now->GetWXWindow() ) , kHIViewWindowContentID , + contentview->GetControlRefAddr() ) ; + if ( !contentview->IsOk() ) + { + // compatibility mode fallback + GetRootControl( (WindowRef) now->GetWXWindow() , contentview->GetControlRefAddr() ) ; } -#endif - return wxWindowBase::IsShownOnScreen(); + // the root control level handler + contentview->InstallEventHandler() ; + return contentview; }