X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b2680ced12cbbed16990007c5fa3ea7730700122..b18e2046af6c8eaf6e867ba18dd9410dbd7dfcf7:/src/osx/carbon/window.cpp?ds=sidebyside diff --git a/src/osx/carbon/window.cpp b/src/osx/carbon/window.cpp index 732447328b..875b62a41e 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: @@ -65,6 +65,8 @@ #include "wx/osx/uma.h" #else #include "wx/osx/private.h" +// bring in themeing +#include #endif #define MAC_SCROLLBAR_SIZE 15 @@ -72,2303 +74,19 @@ #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 - -// -// TODO BEGIN move to window_osx.cpp -// -// =========================================================================== -// implementation -// =========================================================================== - -WX_DECLARE_HASH_MAP(WXWidget, wxWindow*, wxPointerHash, wxPointerEqual, MacControlMap); - -static MacControlMap wxWinMacControlList; - -wxWindowMac *wxFindWindowFromWXWidget(WXWidget inControl ) -{ - MacControlMap::iterator node = wxWinMacControlList.find(inControl); - - return (node == wxWinMacControlList.end()) ? NULL : node->second; -} - -void wxAssociateWindowWithWXWidget(WXWidget inControl, wxWindow *control) -{ - // adding NULL ControlRef is (first) surely a result of an error and - // (secondly) breaks native event processing - wxCHECK_RET( inControl != (WXWidget) NULL, wxT("attempt to add a NULL WindowRef to window list") ); - - wxWinMacControlList[inControl] = control; -} - -void wxRemoveWXWidgetAssociation(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; - } - } - } -} - -// ---------------------------------------------------------------------------- - // constructors and such -// ---------------------------------------------------------------------------- - -wxWindowMac::wxWindowMac() -{ - Init(); -} - -wxWindowMac::wxWindowMac(wxWindowMac *parent, - wxWindowID id, - const wxPoint& pos , - const wxSize& size , - long style , - const wxString& name ) -{ - Init(); - Create(parent, id, pos, size, style, name); -} - -void wxWindowMac::Init() -{ - m_peer = NULL ; - m_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; - - m_macIsUserPane = true; - m_clipChildren = false ; - m_cachedClippedRectValid = false ; -} - -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. - wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent((wxWindow*)this), wxTopLevelWindow); - if ( tlw ) - { - if ( tlw->GetDefaultItem() == (wxButton*) this) - tlw->SetDefaultItem(NULL); - } - - if ( m_peer && m_peer->IsOk() ) - { - m_peer->Destroy() ; - } - - if ( g_MacLastWindow == this ) - g_MacLastWindow = NULL ; - -#ifndef __WXUNIVERSAL__ - wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( (wxWindow*)this ) , wxFrame ) ; - if ( frame ) - { - if ( frame->GetLastFocus() == this ) - frame->SetLastFocus( NULL ) ; - } -#endif - - // delete our drop target if we've got one -#if wxUSE_DRAG_AND_DROP - if ( m_dropTarget != NULL ) - { - delete m_dropTarget; - m_dropTarget = NULL; - } -#endif - - delete m_peer ; -} - -WXWidget wxWindowMac::GetHandle() const -{ - return (WXWidget) m_peer->GetWXWidget() ; -} - -// -// TODO END move to window_osx.cpp -// - -// --------------------------------------------------------------------------- -// 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 - */ - -// -// - -// 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 ) - { -#if wxOSX_USE_CARBON - m_peer = (wxMacControl*) wxWidgetImpl::CreateUserPane( this, pos, size , style, GetExtraStyle() , name ); -#else - m_peer = wxWidgetImpl::CreateUserPane( this, pos, size , style, GetExtraStyle() , name ); -#endif - 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((wxWindow*)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& WXUNUSED(pos), const wxSize& size) -{ - wxASSERT_MSG( m_peer != NULL && m_peer->IsOk() , wxT("No valid mac control") ) ; - -#if wxOSX_USE_CARBON - m_peer->SetReference( (URefCon) this ) ; -#endif - - GetParent()->AddChild( this ); - -#if wxOSX_USE_CARBON - m_peer->InstallEventHandler(); - - ControlRef container = (ControlRef) GetParent()->GetHandle() ; - wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; - ::EmbedControl( m_peer->GetControlRef() , container ) ; -#endif - GetParent()->MacChildAdded() ; - - // adjust font, controlsize etc - DoSetWindowVariant( m_windowVariant ) ; -#if wxOSX_USE_CARBON - m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; -#endif - if (!m_macIsUserPane) - SetInitialSize(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->IsOk()) - return; - -#if wxOSX_USE_COCOA_OR_CARBON - - 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")); - break ; - } - -#if wxOSX_USE_CARBON - m_peer->SetData(kControlEntireControl, kControlSizeTag, &size ) ; -#endif - - wxFont font ; - font.MacCreateFromThemeFont( themeFont ) ; - SetFont( font ) ; -#endif -} - -void wxWindowMac::MacUpdateControlFont() -{ -#if wxOSX_USE_CARBON - m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; -#endif - // 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; -} - -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 ; - - if ( m_peer ) - m_peer->SetBackgroundColour( col ) ; - - return true ; -} - -void wxWindowMac::SetFocus() -{ - if ( !AcceptsFocus() ) - return ; - - wxWindow* former = FindFocus() ; - if ( former == this ) - return ; - - m_peer->SetFocus() ; -} - -void wxWindowMac::DoCaptureMouse() -{ - wxApp::s_captureWindow = (wxWindow*) 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 WXUNUSED(accept)) -{ - // TODO: -} - -// 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 ) ; - - 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 -{ - int width, height; - m_peer->GetSize( width, height ); - - if (x) - *x = width + MacGetLeftBorderSize() + MacGetRightBorderSize() ; - if (y) - *y = height + 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 -{ - int x1, y1; - - m_peer->GetPosition( x1, y1 ) ; - - // 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 -{ - wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ; - wxCHECK_RET( tlw , wxT("TopLevel Window missing") ) ; - tlw->GetNonOwnedPeer()->ScreenToWindow( x, y); - MacRootWindowToWindow( x , y ) ; - - wxPoint origin = GetClientAreaOrigin() ; - if (x) - *x -= origin.x ; - if (y) - *y -= origin.y ; -} - -void wxWindowMac::DoClientToScreen(int *x, int *y) const -{ - wxNonOwnedWindow* tlw = MacGetTopLevelWindow() ; - wxCHECK_RET( tlw , wxT("TopLevel window missing") ) ; - - wxPoint origin = GetClientAreaOrigin() ; - if (x) - *x += origin.x ; - if (y) - *y += origin.y ; - - MacWindowToRootWindow( x , y ) ; - tlw->GetNonOwnedPeer()->WindowToScreen( x , y ); -} - -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::MacWindowToRootWindow( int *x , int *y ) const -{ - wxPoint pt ; - - if (x) - pt.x = *x ; - if (y) - pt.y = *y ; - - if ( !IsTopLevel() ) - { - wxNonOwnedWindow* top = MacGetTopLevelWindow(); - if (top) - { - pt.x -= MacGetLeftBorderSize() ; - pt.y -= MacGetTopBorderSize() ; - wxWidgetImpl::Convert( &pt , m_peer , top->m_peer ) ; - } - } - - if (x) - *x = (int) pt.x ; - if (y) - *y = (int) pt.y ; -} - -void wxWindowMac::MacRootWindowToWindow( int *x , int *y ) const -{ - wxPoint pt ; - - if (x) - pt.x = *x ; - if (y) - pt.y = *y ; - - if ( !IsTopLevel() ) - { - wxNonOwnedWindow* top = MacGetTopLevelWindow(); - if (top) - { - wxWidgetImpl::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 ; -} - -wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const -{ - wxSize sizeTotal = size; - - int innerwidth, innerheight; - int left, top; - int outerwidth, outerheight; - - m_peer->GetContentArea( left, top, innerwidth, innerheight ); - m_peer->GetSize( outerwidth, outerheight ); - - sizeTotal.x += left + (outerwidth-innerwidth); - sizeTotal.y += top + (outerheight-innerheight); - - 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; - - int left, top; - - m_peer->GetContentArea( left, top, ww, hh ); - - 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 ; -#if wxOSX_USE_CARBON - { - wxNonOwnedWindow *tlw = MacGetTopLevelWindow() ; - WindowRef window = (WindowRef) ( tlw ? tlw->GetWXWindow() : 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 = wxFindWindowFromWXWidget( (WXWidget) control ) ; - - } -#endif - - 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 wxOSX_USE_CARBON - if ( m_peer->NeedsFocusRect() /* && m_peer->HasFocus() */ ) - outerBorder += 4 ; -#endif - - if ( outerBorder == 0 ) - return ; - - // now we know that we have something to do at all - - - int tx,ty,tw,th; - - m_peer->GetSize( tw, th ); - m_peer->GetPosition( tx, ty ); - - wxRect leftupdate( tx-outerBorder,ty,outerBorder,th ); - wxRect rightupdate( tx+tw, ty, outerBorder, th ); - wxRect topupdate( tx-outerBorder, ty-outerBorder, tw + 2 * outerBorder, outerBorder ); - wxRect bottomupdate( tx-outerBorder, ty + th, tw + 2 * outerBorder, outerBorder ); - - GetParent()->m_peer->SetNeedsDisplay(&leftupdate); - GetParent()->m_peer->SetNeedsDisplay(&rightupdate); - GetParent()->m_peer->SetNeedsDisplay(&topupdate); - GetParent()->m_peer->SetNeedsDisplay(&bottomupdate); -} - -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()) ) ) ; - - if ( !GetParent()->IsTopLevel() ) - { - bounds.Offset( -GetParent()->MacGetLeftBorderSize(), -GetParent()->MacGetTopBorderSize() ); - } - - MacInvalidateBorders() ; - - m_cachedClippedRectValid = false ; - - m_peer->Move( bounds.x, bounds.y, bounds.width, bounds.height); - - 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 ; - -#if wxOSX_USE_COCOA_OR_CARBON -#if wxOSX_USE_CARBON - m_peer->GetBestRect( &bestsize ) ; -#endif - 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() ; - } - } -#endif - 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 -{ -#if wxOSX_USE_CARBON - 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() ); -#else - return wxPoint(0,0); -#endif -} - -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 wxOSX_USE_CARBON - if ( m_peer && m_peer->IsOk() ) - m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics) ) ; -#endif - - // 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 ) ; - - return true; -} - -void wxWindowMac::DoEnable(bool enable) -{ -#if wxOSX_USE_CARBON - m_peer->Enable( enable ) ; -#endif -} - -// -// status change notifications -// - -void wxWindowMac::MacVisibilityChanged() -{ -} - -void wxWindowMac::MacHiliteChanged() -{ -} - -void wxWindowMac::MacEnabledStateChanged() -{ -#if wxOSX_USE_CARBON - OnEnabled( m_peer->IsEnabled() ); -#endif -} - -// -// status queries on the inherited window's state -// - -bool wxWindowMac::MacIsReallyEnabled() -{ -#if wxOSX_USE_CARBON - return m_peer->IsEnabled() ; -#endif -} - -bool wxWindowMac::MacIsReallyHilited() -{ -#if wxOSX_USE_CARBON - return m_peer->IsActive(); -#endif -} - -int wxWindowMac::GetCharHeight() const -{ - wxClientDC dc( (wxWindow*)this ) ; - - return dc.GetCharHeight() ; -} - -int wxWindowMac::GetCharWidth() const -{ - wxClientDC dc( (wxWindow*)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( (wxWindow*) 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 ; - - m_peer->SetNeedsDisplay( rect ) ; -} - -void wxWindowMac::DoFreeze() -{ -#if wxOSX_USE_CARBON - if ( m_peer && m_peer->IsOk() ) - m_peer->SetDrawingEnabled( false ) ; -#endif -} - -void wxWindowMac::DoThaw() -{ -#if wxOSX_USE_CARBON - if ( m_peer && m_peer->IsOk() ) - { - m_peer->SetDrawingEnabled( true ) ; - m_peer->InvalidateWithChildren() ; - } -#endif -} - -wxWindow *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() ) - { - CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ; - wxASSERT( cgContext ) ; - - int tx,ty,tw,th; - - m_peer->GetSize( tw, th ); - m_peer->GetPosition( tx, ty ); - - Rect rect = { ty,tx, ty+th, tx+tw }; - - - 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 ; - - bool hasFocus = m_peer->NeedsFocusRect() && m_peer->HasFocus() ; - - // back to the surrounding frame rectangle - int tx,ty,tw,th; - - m_peer->GetSize( tw, th ); - m_peer->GetPosition( tx, ty ); - - Rect rect = { ty,tx, ty+th, tx+tw }; - -#if wxOSX_USE_COCOA_OR_CARBON - - 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 - } -#endif // wxOSX_USE_COCOA_OR_CARBON -} - -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 ) ; - - { - wxRect scrollrect( MacGetLeftBorderSize() , MacGetTopBorderSize() , width , height ) ; - if ( rect ) - scrollrect.Intersect( *rect ) ; - // 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 ); - } - - 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 -wxWindow *wxWindowBase::DoFindFocus() -{ -#if wxOSX_USE_CARBON - ControlRef control ; - GetKeyboardFocus( GetUserFocusWindow() , &control ) ; - return wxFindWindowFromWXWidget( (WXWidget) control ) ; -#else - return NULL; -#endif -} - -void wxWindowMac::OnInternalIdle() -{ - // This calls the UI-update mechanism (querying windows for - // menu/toolbar/control state information) - if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen()) - UpdateWindowUI(wxUPDATE_UI_FROMIDLE); -} - -// Raise the window to the top of the Z order -void wxWindowMac::Raise() -{ - m_peer->Raise(); -} - -// Lower the window to the bottom of the Z order -void wxWindowMac::Lower() -{ - m_peer->Lower(); -} - -// 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->Update() ; -} - -wxNonOwnedWindow* wxWindowMac::MacGetTopLevelWindow() const -{ - wxWindowMac *iter = (wxWindowMac*)this ; - - while ( iter ) - { - if ( iter->IsTopLevel() ) - { - wxTopLevelWindow* toplevel = wxDynamicCast(iter,wxTopLevelWindow); - if ( toplevel ) - return toplevel; -#if wxUSE_POPUPWIN - wxPopupWindow* popupwin = wxDynamicCast(iter,wxPopupWindow); - if ( popupwin ) - return popupwin; -#endif - } - iter = iter->GetParent() ; - } - - return NULL ; -} - -const wxRect& wxWindowMac::MacGetClippedClientRect() const -{ - MacUpdateClippedRects() ; - - return m_cachedClippedClientRect ; -} - -const wxRect& wxWindowMac::MacGetClippedRect() const -{ - MacUpdateClippedRects() ; - - return m_cachedClippedRect ; -} - -const wxRect&wxWindowMac:: MacGetClippedRectWithOuterStructure() const -{ - MacUpdateClippedRects() ; - - return m_cachedClippedRectWithOuterStructure ; -} - -const wxRegion& wxWindowMac::MacGetVisibleRegion( bool includeOuterStructures ) -{ - static wxRegion emptyrgn ; - - if ( !m_isBeingDeleted && IsShownOnScreen() ) - { - MacUpdateClippedRects() ; - if ( includeOuterStructures ) - return m_cachedClippedRegionWithOuterStructure ; - else - return m_cachedClippedRegion ; - } - else - { - return emptyrgn ; - } -} - -void wxWindowMac::MacUpdateClippedRects() const -{ -#if wxOSX_USE_CARBON - 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 rIncludingOuterStructures ; - - int tx,ty,tw,th; - - m_peer->GetSize( tw, th ); - m_peer->GetPosition( tx, ty ); - - Rect r = { ty,tx, ty+th, tx+tw }; - - 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 = (wxWindow*) 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 ; -#endif -} - -/* - This function must not change the updatergn ! - */ -bool wxWindowMac::MacDoRedraw( void* updatergnr , long time ) -{ - bool handled = false ; -#if wxOSX_USE_CARBON - 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) ; - } - } - } - } -#endif - return handled ; -} - - -WXWindow wxWindowMac::MacGetTopLevelWindowRef() const -{ - wxNonOwnedWindow* tlw = MacGetTopLevelWindow(); - return tlw ? tlw->GetWXWindow() : NULL ; -} - -bool wxWindowMac::MacHasScrollBarCorner() const -{ - /* Returns whether the scroll bars in a wxScrolledWindow should be - * shortened. Scroll bars should be shortened if either: - * - * - both scroll bars are visible, or - * - * - there is a resize box in the parent frame's corner and this - * window shares the bottom and right edge with the parent - * frame. - */ - - if ( m_hScrollBar == NULL && m_vScrollBar == NULL ) - return false; - - if ( ( m_hScrollBar && m_hScrollBar->IsShown() ) - && ( m_vScrollBar && m_vScrollBar->IsShown() ) ) - { - // Both scroll bars visible - return true; - } - else - { - wxPoint thisWindowBottomRight = GetScreenRect().GetBottomRight(); - - for ( const wxWindow *win = (wxWindow*)this; win; win = win->GetParent() ) - { - const wxFrame *frame = wxDynamicCast( win, wxFrame ) ; - if ( frame ) - { - if ( frame->GetWindowStyleFlag() & wxRESIZE_BORDER ) - { - // Parent frame has resize handle - wxPoint frameBottomRight = frame->GetScreenRect().GetBottomRight(); - - // Note: allow for some wiggle room here as wxMac's - // window rect calculations seem to be imprecise - if ( abs( thisWindowBottomRight.x - frameBottomRight.x ) <= 2 - && abs( thisWindowBottomRight.y - frameBottomRight.y ) <= 2 ) - { - // Parent frame has resize handle and shares - // right bottom corner - return true ; - } - else - { - // Parent frame has resize handle but doesn't - // share right bottom corner - return false ; - } - } - else - { - // Parent frame doesn't have resize handle - return false ; - } - } - } - - // No parent frame found - return false ; - } -} - -void wxWindowMac::MacCreateScrollBars( long style ) -{ - wxASSERT_MSG( m_vScrollBar == NULL && m_hScrollBar == NULL , wxT("attempt to create window twice") ) ; - - if ( style & ( wxVSCROLL | wxHSCROLL ) ) - { - 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() ; -} - -bool wxWindowMac::MacIsChildOfClientArea( const wxWindow* child ) const -{ - bool result = ((child == NULL) || ((child != m_hScrollBar) && (child != m_vScrollBar))); - - return result ; -} - -void wxWindowMac::MacRepositionScrollBars() -{ - 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 ( 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 ); -} - -bool wxWindowMac::AcceptsFocus() const -{ - return m_peer->CanFocus() && wxWindowBase::AcceptsFocus(); -} - -void wxWindowMac::MacSuperChangedPosition() -{ - // 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(); - } -} - -void wxWindowMac::MacTopLevelWindowChangedPosition() -{ - // only screen-absolute structures have to be moved i.e. glcanvas - - wxWindowMac *child; - wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); - while ( node ) - { - child = node->GetData(); - child->MacTopLevelWindowChangedPosition() ; - - node = node->GetNext(); - } -} - -long wxWindowMac::MacGetLeftBorderSize() const -{ - if ( IsTopLevel() ) - return 0 ; - - SInt32 border = 0 ; - - if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER)) - { -#if wxOSX_USE_COCOA_OR_CARBON - // this metric is only the 'outset' outside the simple frame rect - GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ; - border += 1; -#else - border += 2; -#endif - } - else if (HasFlag(wxSIMPLE_BORDER)) - { -#if wxOSX_USE_COCOA_OR_CARBON - // this metric is only the 'outset' outside the simple frame rect - GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; - border += 1; -#else - border += 1; -#endif - } - - 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 ) -{ - return style & ~wxBORDER_MASK ; -} - -// Find the wxWindowMac at the current mouse position, returning the mouse -// position. -wxWindow * wxFindWindowAtPointer( wxPoint& pt ) -{ - pt = wxGetMousePosition(); - wxWindowMac* found = wxFindWindowAtPoint(pt); - - return (wxWindow*) found; -} - -// Get the current mouse position. -wxPoint wxGetMousePosition() -{ - int x, y; - - wxGetMousePosition( &x, &y ); - - return wxPoint(x, y); -} - -void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) -{ - 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 - { - event.Skip() ; - } -} - -void wxWindowMac::OnPaint( wxPaintEvent & WXUNUSED(event) ) -{ -#if wxOSX_USE_COCOA_OR_CARBON - // 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() ) ; - } -#endif -} - -void wxWindowMac::MacHandleControlClick(WXWidget WXUNUSED(control), - wxInt16 WXUNUSED(controlpart), - bool WXUNUSED(mouseStillDown)) -{ -} - -Rect wxMacGetBoundsForControl( wxWindowMac* window , const wxPoint& pos , const wxSize &size , bool adjustForOrigin ) -{ - int x, y, w, h ; - - window->MacGetBoundsForControl( pos , size , x , y, w, h , adjustForOrigin ) ; - Rect bounds = { y, x, y + h, x + w }; - - return bounds ; -} - -wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF WXUNUSED(event) ) -{ -#if wxOSX_USE_COCOA_OR_CARBON - return eventNotHandledErr ; -#else - return 0; +#define wxMAC_DEBUG_REDRAW 0 +#ifndef wxMAC_DEBUG_REDRAW +#define wxMAC_DEBUG_REDRAW 0 #endif -} - -bool wxWindowMac::Reparent(wxWindowBase *newParentBase) -{ - wxWindowMac *newParent = (wxWindowMac *)newParentBase; - if ( !wxWindowBase::Reparent(newParent) ) - return false; - - m_peer->RemoveFromParent(); - m_peer->Embed( GetParent()->GetPeer() ); - return true; -} - -bool wxWindowMac::SetTransparent(wxByte alpha) -{ - SetBackgroundStyle(wxBG_STYLE_TRANSPARENT); - - if ( alpha != m_macAlpha ) - { - m_macAlpha = alpha ; - Refresh() ; - } - return true ; -} - -bool wxWindowMac::CanSetTransparent() -{ - return true ; -} - -wxByte wxWindowMac::GetTransparent() const -{ - return m_macAlpha ; -} - -bool wxWindowMac::IsShownOnScreen() const +// Get the window with the focus +WXWidget wxWidgetImpl::FindFocus() { - if ( m_peer && m_peer->IsOk() ) - { - 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; - } - - return m_peer->IsVisible(); - } - return wxWindowBase::IsShownOnScreen(); + ControlRef control = NULL ; + GetKeyboardFocus( GetUserFocusWindow() , &control ) ; + return control; } -#if wxOSX_USE_CARBON -// -// impl -// - - // --------------------------------------------------------------------------- // Carbon Events // --------------------------------------------------------------------------- @@ -2421,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 - OffsetRgn( allocatedRgn , thisWindow->MacGetLeftBorderSize() , thisWindow->MacGetTopBorderSize() ) ; updateRgn = allocatedRgn ; } } @@ -2500,11 +217,23 @@ 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 ) ; + } + } + thisWindow->MacPaintChildrenBorders(); + } thisWindow->MacSetCGContextRef( NULL ) ; } @@ -2513,7 +242,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl } if ( allocatedRgn ) - DisposeRgn( allocatedRgn ) ; + CFRelease( allocatedRgn ) ; } break ; @@ -2577,8 +306,8 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl thisWindow->GetCaret()->OnKillFocus(); #endif - wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow)); - + wxLogTrace(_T("Focus"), _T("focus lost(%p)"), static_cast(thisWindow)); + // remove this as soon as posting the synthesized event works properly static bool inKillFocusEvent = false ; @@ -2597,7 +326,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(_T("Focus"), _T("focus set(%p)"), static_cast(thisWindow)); wxChildFocusEvent eventFocus((wxWindow*)thisWindow); thisWindow->HandleWindowEvent(eventFocus); @@ -2625,12 +354,12 @@ 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(_T("Focus"), _T("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(_T("Focus"), _T("focus to be lost(%p)"), static_cast(thisWindow)); } ControlPartCode previousControlPart = 0; @@ -2683,7 +412,7 @@ static pascal OSStatus wxMacWindowControlEventHandler( EventHandlerCallRef handl thisWindow->GetCaret()->OnKillFocus(); #endif - wxLogTrace(_T("Focus"), _T("focus lost(%p)"), wx_static_cast(void*, thisWindow)); + wxLogTrace(_T("Focus"), _T("focus lost(%p)"), static_cast(thisWindow)); static bool inKillFocusEvent = false ; @@ -2699,7 +428,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(_T("Focus"), _T("focus set(%p)"), static_cast(thisWindow)); wxChildFocusEvent eventFocus((wxWindow*)thisWindow); thisWindow->HandleWindowEvent(eventFocus); @@ -2727,7 +456,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 ; } } @@ -2989,7 +718,6 @@ wxMacWindowCommandEventHandler(EventHandlerCallRef WXUNUSED(handler), wxMenuItem* item = NULL ; wxMenu* itemMenu = wxFindMenuFromMacCommand( command , item ) ; - int id = wxMacCommandToId( command.commandID ) ; if ( item ) { @@ -2998,11 +726,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 : @@ -3059,13 +789,46 @@ pascal void wxMacLiveScrollbarActionProc( ControlRef control , ControlPartCode p { wxWindow* wx = wxFindWindowFromWXWidget( (WXWidget) control ) ; if ( wx ) - wx->MacHandleControlClick( (WXWidget) control , partCode , true /* stillDown */ ) ; + { + wxEventType scrollEvent = wxEVT_NULL; + switch ( partCode ) + { + case kControlUpButtonPart: + scrollEvent = wxEVT_SCROLL_LINEUP; + break; + + case kControlDownButtonPart: + scrollEvent = wxEVT_SCROLL_LINEDOWN; + break; + + case kControlPageUpPart: + scrollEvent = wxEVT_SCROLL_PAGEUP; + break; + + case kControlPageDownPart: + scrollEvent = wxEVT_SCROLL_PAGEDOWN; + break; + + 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 ) ; -wxWidgetImpl* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, const wxPoint& pos, const wxSize& size, - long style, long extraStyle, const wxString& name) +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 ) ; @@ -3087,11 +850,11 @@ wxWidgetImpl* wxWidgetImpl::CreateUserPane( wxWindowMac* wxpeer, const wxPoint& } -void wxMacControl::MacInstallEventHandler( ControlRef control, wxWindowMac* wxPeer ) +void wxMacControl::InstallEventHandler( WXWidget control ) { - wxAssociateWindowWithWXWidget( (WXWidget) control , wxPeer ) ; - ::InstallControlEventHandler( control , GetwxMacWindowEventHandlerUPP(), - GetEventTypeCount(eventList), eventList, wxPeer, NULL); + wxWidgetImpl::Associate( control ? control : (WXWidget) m_controlRef , this ) ; + ::InstallControlEventHandler( control ? (ControlRef) control : m_controlRef , GetwxMacWindowEventHandlerUPP(), + GetEventTypeCount(eventList), eventList, GetWXPeer(), NULL); } IMPLEMENT_DYNAMIC_CLASS( wxMacControl , wxWidgetImpl ) @@ -3109,44 +872,36 @@ wxMacControl::wxMacControl(wxWindowMac* peer , bool isRootControl ) : wxMacControl::~wxMacControl() { -} + 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") ); -void wxMacControl::Init() -{ + 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; - m_macControlEventHandler = NULL; } -void wxMacControl::Destroy() +void wxMacControl::Init() { - 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") ); - - wxRemoveWXWidgetAssociation( m_wxPeer) ; - // 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; -} - -void wxMacControl::SetReference( URefCon data ) -{ - SetControlReference( m_controlRef , data ); + m_macControlEventHandler = NULL; } void wxMacControl::RemoveFromParent() { // nothing to do here for carbon + HIViewRemoveFromSuperview(m_controlRef); } void wxMacControl::Embed( wxWidgetImpl *parent ) { - // copied from MacPostControlCreate - ControlRef container = (ControlRef) parent->GetWXWidget() ; - wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; - ::EmbedControl( m_controlRef , container ) ; + HIViewAddSubview((ControlRef)parent->GetWXWidget(), m_controlRef); } void wxMacControl::SetNeedsDisplay( const wxRect* rect ) @@ -3175,13 +930,24 @@ void wxMacControl::Lower() void wxMacControl::GetContentArea(int &left , int &top , int &width , int &height) const { - RgnHandle rgn = NewRgn() ; - Rect content ; - if ( GetControlRegion( m_controlRef, kControlContentMetaPart , rgn ) == noErr ) - GetRegionBounds( rgn , &content ) ; + HIShapeRef rgn = NULL; + Rect content ; + + if ( HIViewCopyShape(m_controlRef, kHIViewContentMetaPart, &rgn) == noErr) + { + CGRect cgrect; + HIShapeGetBounds(rgn, &cgrect); + content = (Rect){ cgrect.origin.y, cgrect.origin.x, cgrect.origin.y+cgrect.size.height, cgrect.origin.x+cgrect.size.width }; + CFRelease(rgn); + } else - GetControlBounds( m_controlRef , &content ); - DisposeRgn( rgn ) ; + { + GetControlBounds(m_controlRef, &content); + content.right -= content.left; + content.left = 0; + content.bottom -= content.top; + content.top = 0; + } left = content.left; top = content.top; @@ -3212,6 +978,36 @@ void wxMacControl::GetSize( int &width, int &height ) const height = r.bottom - r.top; } +void wxMacControl::SetControlSize( wxWindowVariant variant ) +{ + ControlSize size ; + switch ( variant ) + { + case wxWINDOW_VARIANT_NORMAL : + size = kControlSizeNormal; + break ; + + case wxWINDOW_VARIANT_SMALL : + size = kControlSizeSmall; + break ; + + case wxWINDOW_VARIANT_MINI : + // not always defined in the headers + size = 3 ; + break ; + + case wxWINDOW_VARIANT_LARGE : + size = kControlSizeLarge; + break ; + + default: + wxFAIL_MSG(_T("unexpected window variant")); + break ; + } + + SetData(kControlEntireControl, kControlSizeTag, &size ) ; +} + void wxMacControl::ScrollRect( const wxRect *rect, int dx, int dy ) { if (GetNeedsDisplay() ) @@ -3299,6 +1095,47 @@ bool wxMacControl::HasFocus() const return control == m_controlRef; } +void wxMacControl::SetCursor(const wxCursor& cursor) +{ + 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 wxMacControl::CaptureMouse() +{ +} + +void wxMacControl::ReleaseMouse() +{ +} + // // subclass specifics // @@ -3342,41 +1179,37 @@ OSStatus wxMacControl::SendHICommand( UInt32 commandID , OptionBits inOptions ) return SendHICommand( command , inOptions ); } -void wxMacControl::Flash( ControlPartCode part , UInt32 ticks ) +void wxMacControl::PerformClick() { - unsigned long finalTicks; - - HiliteControl( m_controlRef , part ); - Delay( ticks , &finalTicks ); - HiliteControl( m_controlRef , kControlNoPart ); + HIViewSimulateClick (m_controlRef, kControlButtonPart, 0, NULL ); } -SInt32 wxMacControl::GetValue() const +wxInt32 wxMacControl::GetValue() const { return ::GetControl32BitValue( m_controlRef ); } -SInt32 wxMacControl::GetMaximum() const +wxInt32 wxMacControl::GetMaximum() const { return ::GetControl32BitMaximum( m_controlRef ); } -SInt32 wxMacControl::GetMinimum() const +wxInt32 wxMacControl::GetMinimum() const { return ::GetControl32BitMinimum( m_controlRef ); } -void wxMacControl::SetValue( SInt32 v ) +void wxMacControl::SetValue( wxInt32 v ) { ::SetControl32BitValue( m_controlRef , v ); } -void wxMacControl::SetMinimum( SInt32 v ) +void wxMacControl::SetMinimum( wxInt32 v ) { ::SetControl32BitMinimum( m_controlRef , v ); } -void wxMacControl::SetMaximum( SInt32 v ) +void wxMacControl::SetMaximum( wxInt32 v ) { ::SetControl32BitMaximum( m_controlRef , v ); } @@ -3396,10 +1229,10 @@ void wxMacControl::SuperChangedPosition() { } -void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle ) +void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , long windowStyle, bool ignoreBlack ) { m_font = font; -#if wxMAC_USE_CORE_TEXT +#if wxOSX_USE_CORE_TEXT if ( UMAGetSystemVersion() >= 0x1050 ) { HIViewPartCode part = 0; @@ -3408,10 +1241,10 @@ void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , l flush = kHIThemeTextHorizontalFlushCenter; else if ( ( windowStyle & wxALIGN_MASK ) & wxALIGN_RIGHT ) flush = kHIThemeTextHorizontalFlushRight; - HIViewSetTextFont( m_controlRef , part , (CTFontRef) font.MacGetCTFont() ); + HIViewSetTextFont( m_controlRef , part , (CTFontRef) font.OSXGetCTFont() ); HIViewSetTextHorizontalFlush( m_controlRef, part, flush ); - if ( foreground != *wxBLACK ) + if ( foreground != *wxBLACK || ignoreBlack == false ) { ControlFontStyleRec fontStyle; foreground.GetRGBColor( &fontStyle.foreColor ); @@ -3420,7 +1253,7 @@ void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , l } } #endif -#if wxMAC_USE_ATSU_TEXT +#if wxOSX_USE_ATSU_TEXT ControlFontStyleRec fontStyle; if ( font.MacGetThemeFontID() != kThemeCurrentPortFont ) { @@ -3449,7 +1282,7 @@ void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , l { fontStyle.font = font.MacGetFontNum(); fontStyle.style = font.MacGetFontStyle(); - fontStyle.size = font.MacGetFontSize(); + fontStyle.size = font.GetPointSize(); fontStyle.flags = kControlUseFontMask | kControlUseFaceMask | kControlUseSizeMask; } @@ -3464,7 +1297,7 @@ void wxMacControl::SetFont( const wxFont & font , const wxColour& foreground , l // 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 ( foreground != *wxBLACK ) + if ( foreground != *wxBLACK || ignoreBlack == false ) { foreground.GetRGBColor( &fontStyle.foreColor ); fontStyle.flags |= kControlUseForeColorMask; @@ -3495,11 +1328,6 @@ void wxMacControl::SetActionProc( ControlActionUPP actionProc ) SetControlAction( m_controlRef , actionProc ); } -void wxMacControl::SetViewSize( SInt32 viewSize ) -{ - SetControlViewSize(m_controlRef , viewSize ); -} - SInt32 wxMacControl::GetViewSize() const { return GetControlViewSize( m_controlRef ); @@ -3554,22 +1382,23 @@ void wxMacControl::GetRectInWindowCoords( Rect *r ) } } -void wxMacControl::GetBestRect( Rect *r ) +void wxMacControl::GetBestRect( wxRect *rect ) const { short baselineoffset; + Rect r = {0,0,0,0}; - GetBestControlRect( m_controlRef , r , &baselineoffset ); + GetBestControlRect( m_controlRef , &r , &baselineoffset ); + *rect = wxRect( r.left, r.top, r.right - r.left, r.bottom-r.top ); } -void wxMacControl::SetLabel( const wxString &title ) +void wxMacControl::GetBestRect( Rect *r ) const { - wxFontEncoding encoding; - - if ( m_font.Ok() ) - encoding = m_font.GetEncoding(); - else - encoding = wxFont::GetDefaultEncoding(); + short baselineoffset; + GetBestControlRect( m_controlRef , r , &baselineoffset ); +} +void wxMacControl::SetLabel( const wxString &title , wxFontEncoding encoding) +{ SetControlTitleWithCFString( m_controlRef , wxCFStringRef( title , encoding ) ); } @@ -3578,10 +1407,8 @@ void wxMacControl::GetFeatures( UInt32 * features ) GetControlFeatures( m_controlRef , features ); } -OSStatus wxMacControl::GetRegion( ControlPartCode partCode , RgnHandle region ) +void wxMacControl::PulseGauge() { - OSStatus err = GetControlRegion( m_controlRef , partCode , region ); - return err; } // SetNeedsDisplay would not invalidate the children @@ -3634,6 +1461,15 @@ wxMacControl* wxMacControl::GetReferenceFromNativeControl(ControlRef control) return NULL; } +void wxMacControl::SetBitmap( const wxBitmap& WXUNUSED(bmp) ) +{ + // implemented in the respective subclasses +} + +void wxMacControl::SetScrollThumb( wxInt32 WXUNUSED(pos), wxInt32 WXUNUSED(viewsize) ) +{ + // implemented in respective subclass +} // // Tab Control @@ -3648,7 +1484,7 @@ OSStatus wxMacControl::SetTabEnabled( SInt16 tabNo , bool enable ) // Control Factory -wxWidgetImpl* wxWidgetImpl::CreateContentView( wxNonOwnedWindow* now ) +wxWidgetImplType* wxWidgetImpl::CreateContentView( wxNonOwnedWindow* now ) { // 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 @@ -3666,5 +1502,3 @@ wxWidgetImpl* wxWidgetImpl::CreateContentView( wxNonOwnedWindow* now ) contentview->InstallEventHandler() ; return contentview; } - -#endif // wxOSX_USE_CARBON