X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/14c9cbdb1e64d22c6ba588d2e46374be393ff7ea..4c200e8d87728306b219822d9c07e28526cd8649:/src/mac/window.cpp?ds=inline diff --git a/src/mac/window.cpp b/src/mac/window.cpp index 868a2c03c5..cf5a48692c 100644 --- a/src/mac/window.cpp +++ b/src/mac/window.cpp @@ -37,6 +37,7 @@ #include "wx/menuitem.h" #include "wx/spinctrl.h" #include "wx/log.h" +#include "wx/geometry.h" #if wxUSE_CARET #include "wx/caret.h" @@ -168,6 +169,13 @@ wxWindowMac::~wxWindowMac() { s_lastMouseWindow = NULL ; } + + wxFrame* frame = wxDynamicCast( wxGetTopLevelParent( this ) , wxFrame ) ; + if ( frame ) + { + if ( frame->GetLastFocus() == this ) + frame->SetLastFocus( NULL ) ; + } if ( gFocusWindow == this ) { @@ -189,6 +197,17 @@ bool wxWindowMac::Create(wxWindowMac *parent, wxWindowID id, { wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindowMac without parent") ); +#if wxUSE_STATBOX + // wxGTK doesn't allow to create controls with static box as the parent so + // this will result in a crash when the program is ported to wxGTK - warn + // about it + // + // the correct solution is to create the controls as siblings of the + // static box + wxASSERT_MSG( !wxDynamicCast(parent, wxStaticBox), + _T("wxStaticBox can't be used as a window parent!") ); +#endif // wxUSE_STATBOX + if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) return FALSE; @@ -219,24 +238,32 @@ void wxWindowMac::SetFocus() { if (gFocusWindow ) { - #if wxUSE_CARET +#if wxUSE_CARET // Deal with caret if ( gFocusWindow->m_caret ) { gFocusWindow->m_caret->OnKillFocus(); } - #endif // wxUSE_CARET - #ifndef __WXUNIVERSAL__ +#endif // wxUSE_CARET +#ifndef __WXUNIVERSAL__ wxControl* control = wxDynamicCast( gFocusWindow , wxControl ) ; if ( control && control->GetMacControl() ) { UMASetKeyboardFocus( (WindowRef) gFocusWindow->MacGetRootWindow() , (ControlHandle) control->GetMacControl() , kControlFocusNoPart ) ; control->MacRedrawControl() ; } - #endif - wxFocusEvent event(wxEVT_KILL_FOCUS, gFocusWindow->m_windowId); - event.SetEventObject(gFocusWindow); - gFocusWindow->GetEventHandler()->ProcessEvent(event) ; +#endif + // Without testing the window id, for some reason + // a kill focus event can still be sent to + // the control just being focussed. + int thisId = this->m_windowId; + int gFocusWindowId = gFocusWindow->m_windowId; + if (gFocusWindowId != thisId) + { + wxFocusEvent event(wxEVT_KILL_FOCUS, gFocusWindow->m_windowId); + event.SetEventObject(gFocusWindow); + gFocusWindow->GetEventHandler()->ProcessEvent(event) ; + } } gFocusWindow = this ; { @@ -345,7 +372,17 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) ::InsertMenu( (MenuHandle) menu->GetHMenu() , -1 ) ; long menuResult = ::PopUpMenuSelect((MenuHandle) menu->GetHMenu() ,y,x, 0) ; - menu->MacMenuSelect( this , TickCount() , HiWord(menuResult) , LoWord(menuResult) ) ; + if ( HiWord(menuResult) != 0 ) + { + MenuCommand id ; + GetMenuItemCommandID( GetMenuHandle(HiWord(menuResult)) , LoWord(menuResult) , &id ) ; + + wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, id ); + event.m_timeStamp = TickCount() ; + event.SetEventObject(this->GetEventHandler()); + event.SetInt( id ); + GetEventHandler()->ProcessEvent(event); + } ::DeleteMenu( menu->MacGetMenuId() ) ; menu->SetInvokingWindow(NULL); @@ -373,9 +410,9 @@ void wxWindowMac::DoScreenToClient(int *x, int *y) const MacRootWindowToWindow( x , y ) ; if ( x ) - x -= MacGetLeftBorderSize() ; + *x -= MacGetLeftBorderSize() ; if ( y ) - y -= MacGetTopBorderSize() ; + *y -= MacGetTopBorderSize() ; } void wxWindowMac::DoClientToScreen(int *x, int *y) const @@ -383,9 +420,9 @@ void wxWindowMac::DoClientToScreen(int *x, int *y) const WindowRef window = (WindowRef) MacGetRootWindow() ; if ( x ) - x += MacGetLeftBorderSize() ; + *x += MacGetLeftBorderSize() ; if ( y ) - y += MacGetTopBorderSize() ; + *y += MacGetTopBorderSize() ; MacWindowToRootWindow( x , y ) ; @@ -587,16 +624,48 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) { // erase former position - Refresh() ; + bool partialRepaint = false ; + + if ( HasFlag(wxNO_FULL_REPAINT_ON_RESIZE) ) + { + wxPoint oldPos( m_x , m_y ) ; + wxPoint newPos( actualX , actualY ) ; + MacWindowToRootWindow( &oldPos.x , &oldPos.y ) ; + MacWindowToRootWindow( &newPos.x , &newPos.y ) ; + if ( oldPos == newPos ) + { + partialRepaint = true ; + RgnHandle oldRgn,newRgn,diffRgn ; + oldRgn = NewRgn() ; + newRgn = NewRgn() ; + diffRgn = NewRgn() ; + SetRectRgn(oldRgn , oldPos.x , oldPos.y , oldPos.x + m_width , oldPos.y + m_height ) ; + SetRectRgn(newRgn , newPos.x , newPos.y , newPos.x + actualWidth , newPos.y + actualHeight ) ; + DiffRgn( newRgn , oldRgn , diffRgn ) ; + InvalWindowRgn( (WindowRef) MacGetRootWindow() , diffRgn ) ; + DiffRgn( oldRgn , newRgn , diffRgn ) ; + InvalWindowRgn( (WindowRef) MacGetRootWindow() , diffRgn ) ; + DisposeRgn(oldRgn) ; + DisposeRgn(newRgn) ; + DisposeRgn(diffRgn) ; + } + } + + if ( !partialRepaint ) + Refresh() ; m_x = actualX ; m_y = actualY ; m_width = actualWidth ; m_height = actualHeight ; + // update any low-level frame-relative positions + + MacUpdateDimensions() ; // erase new position - Refresh() ; + if ( !partialRepaint ) + Refresh() ; if ( doMove ) wxWindowMac::MacSuperChangedPosition() ; // like this only children will be notified @@ -736,13 +805,13 @@ bool wxWindowMac::Show(bool show) void wxWindowMac::MacSuperShown( bool show ) { - wxNode *node = GetChildren().First(); + wxWindowListNode *node = GetChildren().GetFirst(); while ( node ) { - wxWindowMac *child = (wxWindowMac *)node->Data(); + wxWindowMac *child = (wxWindowMac *)node->GetData(); if ( child->m_isShown ) child->MacSuperShown( show ) ; - node = node->Next(); + node = node->GetNext(); } } @@ -754,13 +823,13 @@ void wxWindowMac::MacSuperEnabled( bool enabled ) // because unter MacOSX the frames are drawn with an addXXX mode) // the borders area } - wxNode *node = GetChildren().First(); + wxWindowListNode *node = GetChildren().GetFirst(); while ( node ) { - wxWindowMac *child = (wxWindowMac *)node->Data(); + wxWindowMac *child = (wxWindowMac *)node->GetData(); if ( child->m_isShown ) child->MacSuperEnabled( enabled ) ; - node = node->Next(); + node = node->GetNext(); } } @@ -1189,12 +1258,13 @@ void wxWindowMac::ScrollWindow(int dx, int dy, const wxRect *rect) DisposeRgn( updateRgn ) ; } - for (wxNode *node = GetChildren().First(); node; node = node->Next()) + for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) { - wxWindowMac *child = (wxWindowMac*)node->Data(); + wxWindowMac *child = (wxWindowMac*)node->GetData(); if (child == m_vScrollBar) continue; if (child == m_hScrollBar) continue; if (child->IsTopLevel()) continue; + int x,y; child->GetPosition( &x, &y ); int w,h; @@ -1262,13 +1332,13 @@ void wxWindowMac::OnCommand(wxWindowMac& win, wxCommandEvent& event) wxObject* wxWindowMac::GetChild(int number) const { // Return a pointer to the Nth object in the Panel - wxNode *node = GetChildren().First(); + wxNode *node = GetChildren().GetFirst(); int n = number; while (node && n--) - node = node->Next(); + node = node->GetNext(); if ( node ) { - wxObject *obj = (wxObject *)node->Data(); + wxObject *obj = (wxObject *)node->GetData(); return(obj); } else @@ -1384,9 +1454,9 @@ bool wxWindowMac::MacGetWindowFromPointSub( const wxPoint &point , wxWindowMac** newPoint.y -= m_y; } - for (wxNode *node = GetChildren().First(); node; node = node->Next()) + for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) { - wxWindowMac *child = (wxWindowMac*)node->Data(); + wxWindowMac *child = (wxWindowMac*)node->GetData(); // added the m_isShown test --dmazzoni if ( child->MacGetRootWindow() == window && child->m_isShown ) { @@ -1427,9 +1497,50 @@ bool wxWindowMac::MacGetWindowFromPoint( const wxPoint &screenpoint , wxWindowMa return FALSE ; } -extern int wxBusyCursorCount ; 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 = GetEventHandler()->ProcessEvent(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() ) + { + } + else + { + if ( !GetParent() ) + cursor = *wxSTANDARD_CURSOR ; + } + } + if ( cursor.Ok() ) + cursor.MacInstall() ; + } + return cursor.Ok() ; +} + bool wxWindowMac::MacDispatchMouseEvent(wxMouseEvent& event) { if ((event.m_x < m_x) || (event.m_y < m_y) || @@ -1437,7 +1548,7 @@ bool wxWindowMac::MacDispatchMouseEvent(wxMouseEvent& event) return FALSE; - if ( IsKindOf( CLASSINFO ( wxStaticBox ) ) || IsKindOf( CLASSINFO( wxSpinCtrl ) )) + if ( IsKindOf( CLASSINFO ( wxStaticBox ) ) /* || IsKindOf( CLASSINFO( wxSpinCtrl ) ) */) return FALSE ; WindowRef window = (WindowRef) MacGetRootWindow() ; @@ -1448,9 +1559,9 @@ bool wxWindowMac::MacDispatchMouseEvent(wxMouseEvent& event) int x = event.m_x ; int y = event.m_y ; - for (wxNode *node = GetChildren().First(); node; node = node->Next()) + for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) { - wxWindowMac *child = (wxWindowMac*)node->Data(); + wxWindowMac *child = (wxWindowMac*)node->GetData(); if ( child->MacGetRootWindow() == window && child->IsShown() && child->IsEnabled() ) { if (child->MacDispatchMouseEvent(event)) @@ -1458,14 +1569,18 @@ bool wxWindowMac::MacDispatchMouseEvent(wxMouseEvent& event) } } - event.m_x = x ; - event.m_y = y ; - event.SetEventObject( this ) ; + wxWindow* cursorTarget = this ; + wxPoint cursorPoint( x , y ) ; - if ( wxBusyCursorCount == 0 ) + while( cursorTarget && !cursorTarget->MacSetupCursor( cursorPoint ) ) { - m_cursor.MacInstall() ; + cursorTarget = cursorTarget->GetParent() ; + if ( cursorTarget ) + cursorPoint += cursorTarget->GetPosition() ; } + event.m_x = x ; + event.m_y = y ; + event.SetEventObject( this ) ; if ( event.GetEventType() == wxEVT_LEFT_DOWN ) { @@ -1538,10 +1653,11 @@ wxTopLevelWindowMac* wxWindowMac::MacGetTopLevelWindow() const return win ; } -const wxRegion& wxWindowMac::MacGetVisibleRegion() +const wxRegion& wxWindowMac::MacGetVisibleRegion( bool respectChildrenAndSiblings ) { RgnHandle visRgn = NewRgn() ; RgnHandle tempRgn = NewRgn() ; + RgnHandle tempStaticBoxRgn = NewRgn() ; SetRectRgn( visRgn , 0 , 0 , m_width , m_height ) ; @@ -1551,8 +1667,8 @@ const wxRegion& wxWindowMac::MacGetVisibleRegion() int borderTop = 14 ; int borderOther = 4 ; - SetRectRgn( tempRgn , borderOther , borderTop , m_width - borderOther , m_height - borderOther ) ; - DiffRgn( visRgn , tempRgn , visRgn ) ; + SetRectRgn( tempStaticBoxRgn , borderOther , borderTop , m_width - borderOther , m_height - borderOther ) ; + DiffRgn( visRgn , tempStaticBoxRgn , visRgn ) ; } if ( !IsTopLevel() ) @@ -1565,53 +1681,78 @@ const wxRegion& wxWindowMac::MacGetVisibleRegion() x = y = 0 ; parent->MacWindowToRootWindow( &x, &y ) ; MacRootWindowToWindow( &x , &y ) ; - SetRectRgn( tempRgn , x , y , x + size.x , y + size.y ) ; + + SetRectRgn( tempRgn , + x + parent->MacGetLeftBorderSize() , y + parent->MacGetTopBorderSize() , + x + size.x - parent->MacGetRightBorderSize(), + y + size.y - parent->MacGetBottomBorderSize()) ; + SectRgn( visRgn , tempRgn , visRgn ) ; if ( parent->IsTopLevel() ) break ; parent = parent->GetParent() ; } } - if ( GetWindowStyle() & wxCLIP_CHILDREN ) + if ( respectChildrenAndSiblings ) { - for (wxNode *node = GetChildren().First(); node; node = node->Next()) - { - wxWindowMac *child = (wxWindowMac*)node->Data(); - - if ( !child->IsTopLevel() && child->IsShown() ) + if ( GetWindowStyle() & wxCLIP_CHILDREN ) + { + for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) { - SetRectRgn( tempRgn , child->m_x , child->m_y , child->m_x + child->m_width , child->m_y + child->m_height ) ; - DiffRgn( visRgn , tempRgn , visRgn ) ; - } - } - } + wxWindowMac *child = (wxWindowMac*)node->GetData(); - if ( (GetWindowStyle() & wxCLIP_SIBLINGS) && GetParent() ) - { - bool thisWindowThrough = false ; - for (wxNode *node = GetParent()->GetChildren().First(); node; node = node->Next()) - { - wxWindowMac *sibling = (wxWindowMac*)node->Data(); - if ( sibling == this ) - { - thisWindowThrough = true ; - continue ; - } - if( !thisWindowThrough ) - { - continue ; + if ( !child->IsTopLevel() && child->IsShown() ) + { + SetRectRgn( tempRgn , child->m_x , child->m_y , child->m_x + child->m_width , child->m_y + child->m_height ) ; + if ( child->IsKindOf( CLASSINFO( wxStaticBox ) ) ) + { + int borderTop = 14 ; + int borderOther = 4 ; + + SetRectRgn( tempStaticBoxRgn , child->m_x + borderOther , child->m_y + borderTop , child->m_x + child->m_width - borderOther , child->m_y + child->m_height - borderOther ) ; + DiffRgn( tempRgn , tempStaticBoxRgn , tempRgn ) ; + } + DiffRgn( visRgn , tempRgn , visRgn ) ; + } } + } - if ( !sibling->IsTopLevel() && sibling->IsShown() ) + if ( (GetWindowStyle() & wxCLIP_SIBLINGS) && GetParent() ) + { + bool thisWindowThrough = false ; + for (wxWindowListNode *node = GetParent()->GetChildren().GetFirst(); node; node = node->GetNext()) { - SetRectRgn( tempRgn , sibling->m_x - m_x , sibling->m_y - m_y , sibling->m_x + sibling->m_width - m_x , sibling->m_y + sibling->m_height - m_y ) ; - DiffRgn( visRgn , tempRgn , visRgn ) ; + wxWindowMac *sibling = (wxWindowMac*)node->GetData(); + if ( sibling == this ) + { + thisWindowThrough = true ; + continue ; + } + if( !thisWindowThrough ) + { + continue ; + } + + if ( !sibling->IsTopLevel() && sibling->IsShown() ) + { + SetRectRgn( tempRgn , sibling->m_x - m_x , sibling->m_y - m_y , sibling->m_x + sibling->m_width - m_x , sibling->m_y + sibling->m_height - m_y ) ; + if ( sibling->IsKindOf( CLASSINFO( wxStaticBox ) ) ) + { + int borderTop = 14 ; + int borderOther = 4 ; + + SetRectRgn( tempStaticBoxRgn , sibling->m_x - m_x + borderOther , sibling->m_y - m_y + borderTop , sibling->m_x + sibling->m_width - m_x - borderOther , sibling->m_y + sibling->m_height - m_y - borderOther ) ; + DiffRgn( tempRgn , tempStaticBoxRgn , tempRgn ) ; + } + DiffRgn( visRgn , tempRgn , visRgn ) ; + } } - } + } } m_macVisibleRegion = visRgn ; DisposeRgn( visRgn ) ; DisposeRgn( tempRgn ) ; + DisposeRgn( tempStaticBoxRgn ) ; return m_macVisibleRegion ; } @@ -1643,7 +1784,8 @@ void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase) if ( erase && !EmptyRgn(ownUpdateRgn) ) { wxWindowDC dc(this); - dc.SetClippingRegion(wxRegion(ownUpdateRgn)); + if (!EmptyRgn(ownUpdateRgn)) + dc.SetClippingRegion(wxRegion(ownUpdateRgn)); wxEraseEvent eevent( GetId(), &dc ); eevent.SetEventObject( this ); GetEventHandler()->ProcessEvent( eevent ); @@ -1665,11 +1807,11 @@ void wxWindowMac::MacRedraw( WXHRGN updatergnr , long time, bool erase) // now intersect for each of the children their rect with the updateRgn and call MacRedraw recursively RgnHandle childupdate = NewRgn() ; - for (wxNode *node = GetChildren().First(); node; node = node->Next()) + for (wxWindowListNode *node = GetChildren().GetFirst(); node; node = node->GetNext()) { // calculate the update region for the child windows by intersecting the window rectangle with our own // passed in update region and then offset it to be client-wise window coordinates again - wxWindowMac *child = (wxWindowMac*)node->Data(); + wxWindowMac *child = (wxWindowMac*)node->GetData(); SetRectRgn( childupdate , child->m_x , child->m_y , child->m_x + child->m_width , child->m_y + child->m_height ) ; SectRgn( childupdate , updatergn , childupdate ) ; OffsetRgn( childupdate , -child->m_x , -child->m_y ) ; @@ -1826,12 +1968,12 @@ void wxWindowMac::MacSuperChangedPosition() { // only window-absolute structures have to be moved i.e. controls - wxNode *node = GetChildren().First(); + wxWindowListNode *node = GetChildren().GetFirst(); while ( node ) { - wxWindowMac *child = (wxWindowMac *)node->Data(); + wxWindowMac *child = (wxWindowMac *)node->GetData(); child->MacSuperChangedPosition() ; - node = node->Next(); + node = node->GetNext(); } } @@ -1839,12 +1981,12 @@ void wxWindowMac::MacTopLevelWindowChangedPosition() { // only screen-absolute structures have to be moved i.e. glcanvas - wxNode *node = GetChildren().First(); + wxWindowListNode *node = GetChildren().GetFirst(); while ( node ) { - wxWindowMac *child = (wxWindowMac *)node->Data(); + wxWindowMac *child = (wxWindowMac *)node->GetData(); child->MacTopLevelWindowChangedPosition() ; - node = node->Next(); + node = node->GetNext(); } } long wxWindowMac::MacGetLeftBorderSize( ) const