+ // as all windows are created with WS_VISIBLE style...
+ m_isShown = true;
+
+ m_hScrollBar = NULL ;
+ m_vScrollBar = NULL ;
+ m_macBackgroundBrush = wxNullBrush ;
+
+ m_macIsUserPane = true;
+ m_clipChildren = false ;
+ m_cachedClippedRectValid = false ;
+
+ // we need a valid font for the encodings
+ wxWindowBase::SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
+}
+
+wxWindowMac::~wxWindowMac()
+{
+ 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.
+ wxWindow *parent = GetParent() ;
+ if ( parent )
+ {
+ if (parent->GetDefaultItem() == (wxButton*) this)
+ parent->SetDefaultItem(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() ;
+ }
+
+ if ( g_MacLastWindow == this )
+ g_MacLastWindow = NULL ;
+
+ wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ;
+ if ( frame )
+ {
+ if ( frame->GetLastFocus() == this )
+ frame->SetLastFocus( NULL ) ;
+ }
+
+ // delete our drop target if we've got one
+#if wxUSE_DRAG_AND_DROP
+ if ( m_dropTarget != NULL )
+ {
+ delete m_dropTarget;
+ m_dropTarget = NULL;
+ }
+#endif
+
+ delete m_peer ;
+}
+
+WXWidget wxWindowMac::GetHandle() const
+{
+ return (WXWidget) m_peer->GetControlRef() ;
+}
+
+void wxWindowMac::MacInstallEventHandler( WXWidget control )
+{
+ wxAssociateControlWithMacControl( (ControlRef) control , this ) ;
+ InstallControlEventHandler( (ControlRef)control , GetwxMacWindowEventHandlerUPP(),
+ GetEventTypeCount(eventList), eventList, this,
+ (EventHandlerRef *)&m_macControlEventHandler);
+
+#if !TARGET_API_MAC_OSX
+ if ( (ControlRef) control == m_peer->GetControlRef() )
+ {
+ m_peer->SetData<ControlUserPaneDrawUPP>(kControlEntireControl, kControlUserPaneDrawProcTag, GetwxMacControlUserPaneDrawProc()) ;
+ m_peer->SetData<ControlUserPaneHitTestUPP>(kControlEntireControl, kControlUserPaneHitTestProcTag, GetwxMacControlUserPaneHitTestProc()) ;
+ m_peer->SetData<ControlUserPaneTrackingUPP>(kControlEntireControl, kControlUserPaneTrackingProcTag, GetwxMacControlUserPaneTrackingProc()) ;
+ m_peer->SetData<ControlUserPaneIdleUPP>(kControlEntireControl, kControlUserPaneIdleProcTag, GetwxMacControlUserPaneIdleProc()) ;
+ m_peer->SetData<ControlUserPaneKeyDownUPP>(kControlEntireControl, kControlUserPaneKeyDownProcTag, GetwxMacControlUserPaneKeyDownProc()) ;
+ m_peer->SetData<ControlUserPaneActivateUPP>(kControlEntireControl, kControlUserPaneActivateProcTag, GetwxMacControlUserPaneActivateProc()) ;
+ m_peer->SetData<ControlUserPaneFocusUPP>(kControlEntireControl, kControlUserPaneFocusProcTag, GetwxMacControlUserPaneFocusProc()) ;
+ m_peer->SetData<ControlUserPaneBackgroundUPP>(kControlEntireControl, kControlUserPaneBackgroundProcTag, GetwxMacControlUserPaneBackgroundProc()) ;
+ }
+#endif
+}
+
+// Constructor
+bool wxWindowMac::Create(wxWindowMac *parent,
+ wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ wxCHECK_MSG( parent, false, wxT("can't create wxWindowMac without parent") );
+
+ if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
+ return false;
+
+ m_windowVariant = parent->GetWindowVariant() ;
+
+ if ( m_macIsUserPane )
+ {
+ 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) ;
+ }
+
+#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))))
+ {
+ MacCreateScrollBars( style ) ;
+ }
+#endif
+
+ wxWindowCreateEvent event(this);
+ GetEventHandler()->AddPendingEvent(event);
+
+ return true;
+}
+
+void wxWindowMac::MacChildAdded()
+{
+ if ( m_vScrollBar )
+ m_vScrollBar->Raise() ;
+ if ( m_hScrollBar )
+ m_hScrollBar->Raise() ;
+}
+
+void wxWindowMac::MacPostControlCreate(const wxPoint& pos, const wxSize& size)
+{
+ wxASSERT_MSG( m_peer != NULL && m_peer->Ok() , wxT("No valid mac control") ) ;
+
+ m_peer->SetReference( (long)this ) ;
+ GetParent()->AddChild( this );
+
+ 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) ) ;
+
+ if (!m_macIsUserPane)
+ 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_peer->Ok() ) ;
+
+ m_windowVariant = variant ;
+
+ if (m_peer == NULL || !m_peer->Ok())
+ return;
+
+ 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 :
+ if (UMAGetSystemVersion() >= 0x1030 )
+ {
+ // not always defined in the headers
+ size = 3 ;
+ themeFont = 109 ;
+ }
+ else
+ {
+ size = kControlSizeSmall;
+ themeFont = kThemeSmallSystemFont ;
+ }
+ break ;
+
+ case wxWINDOW_VARIANT_LARGE :
+ size = kControlSizeLarge;
+ themeFont = kThemeSystemFont ;
+ break ;
+
+ default:
+ wxFAIL_MSG(_T("unexpected window variant"));
+ break ;
+ }
+
+ m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
+
+ wxFont font ;
+ font.MacCreateThemeFont( themeFont ) ;
+ SetFont( font ) ;
+}
+
+void wxWindowMac::MacUpdateControlFont()
+{
+ m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ;
+ Refresh() ;
+}
+
+bool wxWindowMac::SetFont(const wxFont& font)
+{
+ bool retval = wxWindowBase::SetFont( font );
+
+ MacUpdateControlFont() ;
+
+ return retval;
+}
+
+bool wxWindowMac::SetForegroundColour(const wxColour& col )
+{
+ bool retval = wxWindowBase::SetForegroundColour( col );
+
+ if (retval)
+ MacUpdateControlFont();
+
+ return retval;
+}
+
+bool wxWindowMac::SetBackgroundColour(const wxColour& col )
+{
+ if ( !wxWindowBase::SetBackgroundColour(col) && m_hasBgCol )
+ return false ;
+
+ wxBrush brush ;
+ wxColour newCol(GetBackgroundColour());
+
+ if ( newCol == wxSystemSettings::GetColour( wxSYS_COLOUR_APPWORKSPACE ) )
+ brush.MacSetTheme( kThemeBrushDocumentWindowBackground ) ;
+ else if ( newCol == wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) )
+ brush.MacSetTheme( kThemeBrushDialogBackgroundActive ) ;
+ else
+ brush.SetColour( newCol ) ;
+
+ MacSetBackgroundBrush( brush ) ;
+ MacUpdateControlFont() ;
+
+ return true ;
+}
+
+void wxWindowMac::MacSetBackgroundBrush( const wxBrush &brush )
+{
+ m_macBackgroundBrush = brush ;
+ m_peer->SetBackground( brush ) ;
+}
+
+bool wxWindowMac::MacCanFocus() 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,
+ // but the value range is nowhere documented
+ Boolean keyExistsAndHasValidFormat ;
+ CFIndex fullKeyboardAccess = CFPreferencesGetAppIntegerValue( CFSTR("AppleKeyboardUIMode" ) ,
+ kCFPreferencesCurrentApplication, &keyExistsAndHasValidFormat );
+
+ if ( keyExistsAndHasValidFormat && fullKeyboardAccess > 0 )
+ {
+ return true ;
+ }
+ else
+ {
+ UInt32 features = 0 ;
+ m_peer->GetFeatures( &features ) ;
+
+ return features & ( kControlSupportsFocus | kControlGetsFocusOnClick ) ;
+ }
+}
+
+void wxWindowMac::SetFocus()
+{
+ if ( !AcceptsFocus() )
+ return ;
+
+ wxWindow* former = FindFocus() ;
+ if ( former == this )
+ return ;
+
+ // 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
+ OSStatus err = m_peer->SetFocus( kControlFocusNextPart ) ;
+ if ( err == errCouldntSetFocus )
+ return ;
+
+ SetUserFocusWindow( (WindowRef)MacGetTopLevelWindowRef() );
+
+#if !TARGET_API_MAC_OSX
+ // emulate carbon events when running under CarbonLib where they are not natively available
+ if ( former )
+ {
+ EventRef evRef = NULL ;
+
+ err = MacCreateEvent(
+ NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) ,
+ kEventAttributeUserEvent , &evRef );
+ verify_noerr( err );
+
+ wxMacCarbonEvent cEvent( evRef ) ;
+ cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) former->GetHandle() ) ;
+ cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNoPart ) ;
+
+ wxMacWindowEventHandler( NULL , evRef , former ) ;
+ ReleaseEvent( evRef ) ;
+ }
+
+ // send new focus event
+ {
+ EventRef evRef = NULL ;
+
+ err = MacCreateEvent(
+ NULL , kEventClassControl , kEventControlSetFocusPart , TicksToEventTime( TickCount() ) ,
+ kEventAttributeUserEvent , &evRef );
+ verify_noerr( err );
+
+ wxMacCarbonEvent cEvent( evRef ) ;
+ cEvent.SetParameter<ControlRef>( kEventParamDirectObject , (ControlRef) GetHandle() ) ;
+ cEvent.SetParameter<ControlPartCode>(kEventParamControlPart , typeControlPartCode , kControlFocusNextPart ) ;
+
+ wxMacWindowEventHandler( NULL , evRef , this ) ;
+ ReleaseEvent( evRef ) ;
+ }
+#endif
+}
+
+void wxWindowMac::DoCaptureMouse()
+{
+ wxApp::s_captureWindow = this ;
+}
+
+wxWindow * wxWindowBase::GetCapture()
+{
+ return wxApp::s_captureWindow ;
+}
+
+void wxWindowMac::DoReleaseMouse()
+{
+ wxApp::s_captureWindow = NULL ;
+}
+
+#if wxUSE_DRAG_AND_DROP
+
+void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
+{
+ if ( m_dropTarget != NULL )
+ delete m_dropTarget;
+
+ m_dropTarget = pDropTarget;
+ if ( m_dropTarget != NULL )
+ {
+ // TODO:
+ }
+}
+
+#endif
+
+// Old-style File Manager Drag & Drop
+void wxWindowMac::DragAcceptFiles(bool accept)
+{
+ // TODO:
+}
+
+// Returns the size of the native control. In the case of the toplevel window
+// this is the content area root control
+
+void wxWindowMac::MacGetPositionAndSizeFromControl(int& x, int& y,
+ int& w, int& h) const
+{
+ wxFAIL_MSG( wxT("Not currently supported") ) ;
+}
+
+// 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
+{
+ // 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 ) ;
+
+ bool isCompositing = MacGetTopLevelWindow()->MacUsesCompositing() ;
+ if ( !isCompositing )
+ GetParent()->MacWindowToRootWindow( &x , &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 ;
+}
+
+// Get window size (not client size)
+void wxWindowMac::DoGetSize(int *x, int *y) const
+{
+ Rect bounds ;
+ m_peer->GetRect( &bounds ) ;
+
+ if (x)
+ *x = bounds.right - bounds.left + MacGetLeftBorderSize() + MacGetRightBorderSize() ;
+ if (y)
+ *y = bounds.bottom - bounds.top + MacGetTopBorderSize() + MacGetBottomBorderSize() ;
+}
+
+// get the position of the bounds of this window in client coordinates of its parent
+void wxWindowMac::DoGetPosition(int *x, int *y) const
+{
+ Rect bounds ;
+ m_peer->GetRect( &bounds ) ;
+
+ int x1 = bounds.left ;
+ int y1 = bounds.top ;
+
+ // 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 ;
+ }
+ }
+
+ if (x)
+ *x = x1 ;
+ if (y)
+ *y = y1 ;
+}
+
+void wxWindowMac::DoScreenToClient(int *x, int *y) const
+{
+ 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 ;
+
+ QDGlobalToLocalPoint( GetWindowPort( window ) , &localwhere ) ;
+
+ 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 ;
+}
+
+void wxWindowMac::DoClientToScreen(int *x, int *y) const
+{
+ 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 ) ;
+
+ Point localwhere = { 0, 0 };
+ if (x)
+ localwhere.h = *x ;
+ if (y)
+ localwhere.v = *y ;
+
+ QDLocalToGlobalPoint( GetWindowPort( window ) , &localwhere ) ;
+
+ if (x)
+ *x = localwhere.h ;
+ if (y)
+ *y = localwhere.v ;
+}
+
+void wxWindowMac::MacClientToRootWindow( int *x , int *y ) const
+{
+ wxPoint origin = GetClientAreaOrigin() ;
+ if (x)
+ *x += origin.x ;
+ if (y)
+ *y += origin.y ;
+
+ MacWindowToRootWindow( x , y ) ;
+}
+
+void wxWindowMac::MacRootWindowToClient( int *x , int *y ) const
+{
+ MacRootWindowToWindow( x , y ) ;
+
+ wxPoint origin = GetClientAreaOrigin() ;
+ if (x)
+ *x -= origin.x ;
+ if (y)
+ *y -= origin.y ;
+}
+
+void wxWindowMac::MacWindowToRootWindow( int *x , int *y ) const
+{
+ wxPoint pt ;
+
+ if (x)
+ pt.x = *x ;
+ if (y)
+ pt.y = *y ;
+
+ if ( !IsTopLevel() )
+ {
+ 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 ;
+}
+
+void wxWindowMac::MacWindowToRootWindow( short *x , short *y ) const
+{
+ int x1 , y1 ;
+
+ if (x)
+ x1 = *x ;
+ if (y)
+ y1 = *y ;
+
+ MacWindowToRootWindow( &x1 , &y1 ) ;
+
+ if (x)
+ *x = x1 ;
+ if (y)
+ *y = y1 ;
+}
+
+void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const
+{
+ wxPoint pt ;
+
+ if (x)
+ pt.x = *x ;
+ if (y)
+ pt.y = *y ;
+
+ if ( !IsTopLevel() )
+ {
+ wxTopLevelWindowMac* top = MacGetTopLevelWindow();
+ if (top)
+ {
+ wxMacControl::Convert( &pt , top->m_peer , m_peer ) ;
+ pt.x += MacGetLeftBorderSize() ;
+ pt.y += MacGetTopBorderSize() ;
+ }
+ }
+
+ if (x)
+ *x = (int) pt.x ;
+ if (y)
+ *y = (int) pt.y ;
+}
+
+void wxWindowMac::MacRootWindowToWindow( short *x , short *y ) const
+{
+ int x1 , y1 ;
+
+ if (x)
+ x1 = *x ;
+ if (y)
+ y1 = *y ;
+
+ MacRootWindowToWindow( &x1 , &y1 ) ;
+
+ if (x)
+ *x = x1 ;
+ if (y)
+ *y = y1 ;
+}
+
+void wxWindowMac::MacGetContentAreaInset( int &left , int &top , int &right , int &bottom )
+{
+ RgnHandle rgn = NewRgn() ;
+
+ 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 == cursor)
+ return false;
+
+ if (wxNullCursor == cursor)
+ {
+ 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 ;
+ {
+ wxTopLevelWindowMac *tlw = MacGetTopLevelWindow() ;
+ WindowRef window = (WindowRef) ( tlw ? tlw->MacGetWindowRef() : 0 ) ;
+ CGrafPtr savePort ;
+ Boolean swapped = QDSwapPort( GetWindowPort( window ) , &savePort ) ;
+
+ // TODO: If we ever get a GetCurrentEvent... replacement
+ // for the mouse position, use it...
+
+ Point pt ;
+ ControlPartCode part ;
+ ControlRef control ;
+
+ GetMouse( &pt ) ;
+ control = wxMacFindControlUnderMouse( tlw , pt , window , &part ) ;
+ if ( control )
+ mouseWin = wxFindControlFromMacControl( control ) ;
+
+ if ( swapped )
+ QDSwapPort( savePort , NULL ) ;
+ }
+
+ if ( mouseWin == this && !wxIsBusy() )
+ m_cursor.MacInstall() ;
+
+ return true ;
+}
+
+#if wxUSE_MENUS
+bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y)
+{
+ menu->SetInvokingWindow(this);
+ menu->UpdateUI();
+
+ 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) ;
+ 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;
+}
+#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 = MacIsReallyShown() ;
+ 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 ) ;
+
+#ifdef __WXMAC_OSX__
+ GetParent()->m_peer->SetNeedsDisplay( updateOuter ) ;
+#else
+ WindowRef tlw = (WindowRef) MacGetTopLevelWindowRef() ;
+ if ( tlw )
+ InvalWindowRgn( tlw , updateOuter ) ;
+#endif
+
+ 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);
+ GetEventHandler()->ProcessEvent(event) ;
+ }
+
+ if ( doResize )
+ {
+ MacRepositionScrollBars() ;
+ wxSize size(actualWidth, actualHeight);
+ wxSizeEvent event(size, m_windowId);
+ event.SetEventObject(this);
+ GetEventHandler()->ProcessEvent(event);
+ }
+ }
+}
+
+wxSize wxWindowMac::DoGetBestSize() const
+{
+ if ( m_macIsUserPane || IsTopLevel() )
+ return wxWindowBase::DoGetBestSize() ;
+
+ 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 ;
+ bestHeight = bestsize.bottom - bestsize.top ;
+ 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)