X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/524c47aa3adf2af11a3069fd5da035a604f08f66..b85b06e13d22e7fc1604ec1a49caa1227a1b3d36:/src/osx/window_osx.cpp?ds=sidebyside diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 24c45ddb07..f86cdec15c 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -61,6 +61,8 @@ #include "wx/dnd.h" #endif +#include "wx/graphics.h" + #if wxOSX_USE_CARBON #include "wx/osx/uma.h" #else @@ -83,7 +85,6 @@ 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() @@ -139,8 +140,6 @@ wxWindowMac::~wxWindowMac() { SendDestroyEvent(); - m_isBeingDeleted = true; - MacInvalidateBorders() ; #ifndef __WXUNIVERSAL__ @@ -151,7 +150,7 @@ wxWindowMac::~wxWindowMac() if ( frame ) { if ( frame->GetLastFocus() == this ) - frame->SetLastFocus((wxWindow*)NULL); + frame->SetLastFocus(NULL); break; } } @@ -196,13 +195,11 @@ wxWindowMac::~wxWindowMac() WXWidget wxWindowMac::GetHandle() const { - return (WXWidget) m_peer->GetWXWidget() ; + if ( m_peer ) + return (WXWidget) m_peer->GetWXWidget() ; + return NULL; } -// -// TODO END move to window_osx.cpp -// - // --------------------------------------------------------------------------- // Utility Routines to move between different coordinate systems // --------------------------------------------------------------------------- @@ -272,19 +269,11 @@ void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSiz { 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(); + m_peer->Embed(GetParent()->GetPeer()); - 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 @@ -292,7 +281,8 @@ void wxWindowMac::MacPostControlCreate(const wxPoint& WXUNUSED(pos), const wxSiz m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ; - if (!m_macIsUserPane) + // for controls we want to use best size for wxDefaultSize params ) + if ( !m_macIsUserPane ) SetInitialSize(size); SetCursor( *wxSTANDARD_CURSOR ) ; @@ -310,12 +300,8 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant ) return; m_peer->SetControlSize( variant ); -#if wxOSX_USE_COCOA_OR_CARBON - wxFont font ; - #if wxOSX_USE_CARBON ControlSize size ; - ThemeFontID themeFont = kThemeSystemFont ; // we will get that from the settings later // and make this NORMAL later, but first @@ -325,68 +311,65 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant 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 ; } - m_peer->SetData(kControlEntireControl, kControlSizeTag, &size ) ; - font.MacCreateFromThemeFont( themeFont ) ; -#else - CTFontUIFontType themeFont = kCTFontSystemFontType ; +#endif + + wxFont font ; + + wxOSXSystemFont systemFont = wxOSX_SYSTEM_FONT_NORMAL ; + switch ( variant ) { case wxWINDOW_VARIANT_NORMAL : - themeFont = kCTFontSystemFontType; + systemFont = wxOSX_SYSTEM_FONT_NORMAL ; break ; case wxWINDOW_VARIANT_SMALL : - themeFont = kCTFontSmallSystemFontType; + systemFont = wxOSX_SYSTEM_FONT_SMALL ; break ; case wxWINDOW_VARIANT_MINI : - themeFont = kCTFontMiniSystemFontType; + systemFont = wxOSX_SYSTEM_FONT_MINI ; break ; case wxWINDOW_VARIANT_LARGE : - themeFont = kCTFontSystemFontType; + systemFont = wxOSX_SYSTEM_FONT_NORMAL ; break ; default: wxFAIL_MSG(_T("unexpected window variant")); break ; } - font.MacCreateFromUIFont( themeFont ) ; -#endif + + font.CreateSystemFont( systemFont ) ; SetFont( font ) ; -#endif } void wxWindowMac::MacUpdateControlFont() { -#if wxOSX_USE_CARBON - m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; -#endif + if ( m_peer ) + m_peer->SetFont( GetFont() , GetForegroundColour() , GetWindowStyle() ) ; + // do not trigger refreshes upon invisible and possible partly created objects if ( IsShownOnScreen() ) Refresh() ; @@ -437,6 +420,7 @@ void wxWindowMac::SetFocus() void wxWindowMac::DoCaptureMouse() { wxApp::s_captureWindow = (wxWindow*) this ; + m_peer->CaptureMouse() ; } wxWindow * wxWindowBase::GetCapture() @@ -447,14 +431,15 @@ wxWindow * wxWindowBase::GetCapture() void wxWindowMac::DoReleaseMouse() { wxApp::s_captureWindow = NULL ; + + m_peer->ReleaseMouse() ; } #if wxUSE_DRAG_AND_DROP void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget) { - if ( m_dropTarget != NULL ) - delete m_dropTarget; + delete m_dropTarget; m_dropTarget = pDropTarget; if ( m_dropTarget != NULL ) @@ -483,9 +468,8 @@ bool wxWindowMac::MacGetBoundsForControl( 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 ) ; + w = WidthDefault( size.x ); + h = HeightDefault( size.y ); x += MacGetLeftBorderSize() ; y += MacGetTopBorderSize() ; @@ -496,7 +480,7 @@ bool wxWindowMac::MacGetBoundsForControl( 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() ) + if ( GetParent() && !GetParent()->IsTopLevel() ) { x -= GetParent()->MacGetLeftBorderSize() ; y -= GetParent()->MacGetTopBorderSize() ; @@ -654,8 +638,8 @@ wxSize wxWindowMac::DoGetSizeFromClientSize( const wxSize & size ) const m_peer->GetContentArea( left, top, innerwidth, innerheight ); m_peer->GetSize( outerwidth, outerheight ); - sizeTotal.x += left + (outerwidth-innerwidth); - sizeTotal.y += top + (outerheight-innerheight); + sizeTotal.x += outerwidth-innerwidth; + sizeTotal.y += outerheight-innerheight; sizeTotal.x += MacGetLeftBorderSize() + MacGetRightBorderSize() ; sizeTotal.y += MacGetTopBorderSize() + MacGetBottomBorderSize() ; @@ -703,37 +687,8 @@ bool wxWindowMac::SetCursor(const wxCursor& cursor) 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() ; + if ( GetPeer() != NULL ) + GetPeer()->SetCursor( m_cursor ); return true ; } @@ -755,32 +710,8 @@ bool wxWindowMac::DoPopupMenu(wxMenu *menu, int x, int y) { ClientToScreen( &x , &y ) ; } -#ifdef __WXOSX_CARBON__ - 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 ); -#else + menu->GetPeer()->PopUp(this, x, y); menu->SetInvokingWindow( NULL ); - return false; -#endif - return true; #else // actually this shouldn't be called, because universal is having its own implementation @@ -815,16 +746,14 @@ void wxWindowMac::MacInvalidateBorders() return ; int outerBorder = MacGetLeftBorderSize() ; -#if wxOSX_USE_CARBON - if ( m_peer->NeedsFocusRect() /* && m_peer->HasFocus() */ ) + + if ( m_peer->NeedsFocusRect() ) outerBorder += 4 ; -#endif if ( outerBorder == 0 ) return ; // now we know that we have something to do at all - int tx,ty,tw,th; @@ -836,10 +765,12 @@ void wxWindowMac::MacInvalidateBorders() 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); + if (GetParent()) { + 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) @@ -864,6 +795,8 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) int actualX = x; int actualY = y; +#if 0 + // min and max sizes are only for sizers, not for explicit size setting if ((m_minWidth != -1) && (actualWidth < m_minWidth)) actualWidth = m_minWidth; if ((m_minHeight != -1) && (actualHeight < m_minHeight)) @@ -872,6 +805,7 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) actualWidth = m_maxWidth; if ((m_maxHeight != -1) && (actualHeight > m_maxHeight)) actualHeight = m_maxHeight; +#endif bool doMove = false, doResize = false ; @@ -889,9 +823,9 @@ void wxWindowMac::DoMoveWindow(int x, int y, int width, int height) wxSize( actualWidth - (MacGetLeftBorderSize() + MacGetRightBorderSize()) , actualHeight - (MacGetTopBorderSize() + MacGetBottomBorderSize()) ) ) ; - if ( !GetParent()->IsTopLevel() ) + if ( parent && !parent->IsTopLevel() ) { - bounds.Offset( -GetParent()->MacGetLeftBorderSize(), -GetParent()->MacGetTopBorderSize() ); + bounds.Offset( -parent->MacGetLeftBorderSize(), -parent->MacGetTopBorderSize() ); } MacInvalidateBorders() ; @@ -994,6 +928,13 @@ void wxWindowMac::DoSetSize(int x, int y, int width, int height, int sizeFlags) // TODO: REMOVE MacRepositionScrollBars() ; // we might have a real position shift + if (sizeFlags & wxSIZE_FORCE_EVENT) + { + wxSizeEvent event( wxSize(width,height), GetId() ); + event.SetEventObject( this ); + HandleWindowEvent( event ); + } + return; } @@ -1068,7 +1009,7 @@ void wxWindowMac::SetLabel(const wxString& title) { m_label = title ; - if ( m_peer && m_peer->IsOk() ) + if ( m_peer && m_peer->IsOk() && !(IsKindOf( CLASSINFO(wxButton) ) && GetId() == wxID_HELP) ) m_peer->SetLabel( wxStripMenuCodes(m_label, wxStrip_Mnemonics), GetFont().GetEncoding() ) ; // do not trigger refreshes upon invisible and possible partly created objects @@ -1134,20 +1075,25 @@ bool wxWindowMac::MacIsReallyHilited() int wxWindowMac::GetCharHeight() const { - wxClientDC dc( (wxWindow*)this ) ; + wxCoord height; + GetTextExtent( wxT("g") , NULL , &height , NULL , NULL , NULL ); - return dc.GetCharHeight() ; + return height; } int wxWindowMac::GetCharWidth() const { - wxClientDC dc( (wxWindow*)this ) ; + wxCoord width; + GetTextExtent( wxT("g") , &width , NULL , NULL , NULL , NULL ); - return dc.GetCharWidth() ; + return width; } -void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, - int *descent, int *externalLeading, const wxFont *theFont ) const +void wxWindowMac::DoGetTextExtent(const wxString& str, + int *x, int *y, + int *descent, + int *externalLeading, + const wxFont *theFont) const { const wxFont *fontToUse = theFont; wxFont tempFont; @@ -1157,17 +1103,22 @@ void wxWindowMac::GetTextExtent(const wxString& string, int *x, int *y, fontToUse = &tempFont; } - wxClientDC dc( (wxWindow*) this ) ; - wxCoord lx,ly,ld,le ; - dc.GetTextExtent( string , &lx , &ly , &ld, &le, (wxFont *)fontToUse ) ; + wxGraphicsContext* ctx = wxGraphicsContext::Create(); + ctx->SetFont( *fontToUse, *wxBLACK ); + + wxDouble h , d , e , w; + ctx->GetTextExtent( str, &w, &h, &d, &e ); + + delete ctx; + if ( externalLeading ) - *externalLeading = le ; + *externalLeading = (wxCoord)(e+0.5); if ( descent ) - *descent = ld ; + *descent = (wxCoord)(d+0.5); if ( x ) - *x = lx ; + *x = (wxCoord)(w+0.5); if ( y ) - *y = ly ; + *y = (wxCoord)(h+0.5); } /* @@ -1360,7 +1311,6 @@ void wxWindowMac::MacPaintGrowBox() 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() ) @@ -1399,50 +1349,35 @@ void wxWindowMac::MacPaintBorders( int WXUNUSED(leftOrigin) , int WXUNUSED(right 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) ) + if ( m_peer->NeedsFrame() ) { - info.kind = kHIThemeFrameListBox ; - HIThemeDrawFrame( &cgrect , &info , cgContext , kHIThemeOrientationNormal ) ; + HIThemeFrameDrawInfo info ; + memset( &info, 0 , sizeof(info) ) ; + + info.version = 0 ; + info.kind = 0 ; + info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; + info.isFocused = hasFocus ; + + 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 ) + + 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 } @@ -1582,16 +1517,9 @@ void wxWindowMac::MacOnScroll( wxScrollEvent &event ) } } -// 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 + return wxFindWindowFromWXWidget(wxWidgetImpl::FindFocus()); } void wxWindowMac::OnInternalIdle() @@ -1835,104 +1763,96 @@ void wxWindowMac::MacUpdateClippedRects() const /* This function must not change the updatergn ! */ -bool wxWindowMac::MacDoRedraw( void* updatergnr , long time ) +bool wxWindowMac::MacDoRedraw( long time ) { bool handled = false ; -#if wxOSX_USE_CARBON - Rect updatebounds ; - RgnHandle updatergn = (RgnHandle) updatergnr ; - GetRegionBounds( updatergn , &updatebounds ) ; + + wxRegion formerUpdateRgn = m_updateRegion; + wxRegion clientUpdateRgn = formerUpdateRgn; - // wxLogDebug(wxT("update for %s bounds %d, %d, %d, %d"), wxString(GetClassInfo()->GetClassName()).c_str(), updatebounds.left, updatebounds.top , updatebounds.right , updatebounds.bottom ) ; + wxSize sz = GetClientSize() ; + wxPoint origin = GetClientAreaOrigin() ; + + clientUpdateRgn.Intersect(origin.x , origin.y , origin.x + sz.x , origin.y + sz.y); + + // 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->SetDeviceClippingRegion(formerUpdateRgn); + else + dc->SetDeviceClippingRegion(clientUpdateRgn); - 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 ) ; + wxEraseEvent eevent( GetId(), dc ); + eevent.SetEventObject( this ); + HandleWindowEvent( eevent ); + delete dc ; + } - // 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))); + MacPaintGrowBox(); - wxEraseEvent eevent( GetId(), dc ); - eevent.SetEventObject( this ); - HandleWindowEvent( eevent ); - delete dc ; - } + // calculate a client-origin version of the update rgn and set m_updateRegion to that + clientUpdateRgn.Offset( -origin.x , -origin.y ); + m_updateRegion = clientUpdateRgn ; - MacPaintGrowBox(); + if ( !m_updateRegion.Empty() ) + { + // paint the window itself - // 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 ) ; + wxPaintEvent event(GetId()); + event.SetTimestamp(time); + event.SetEventObject(this); + handled = HandleWindowEvent(event); + } - if ( !m_updateRegion.Empty() ) - { - // paint the window itself + m_updateRegion = formerUpdateRgn; + return handled; +} - wxPaintEvent event; - event.SetTimestamp(time); - event.SetEventObject(this); - HandleWindowEvent(event); - handled = true ; - } +void wxWindowMac::MacPaintChildrenBorders() +{ + // 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; - // 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() ; + // only draw those in the update region (add a safety margin of 10 pixels for shadow effects - wxWindowMac *child; - int x, y, w, h; - for (wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; node = node->GetNext()) + child->GetPosition( &x, &y ); + child->GetSize( &w, &h ); + + if ( m_updateRegion.Contains(clientOrigin.x+x-10, clientOrigin.y+y-10, w+20, h+20) ) { - 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 ) ) { - // paint custom borders - wxNcPaintEvent eventNc( child->GetId() ); - eventNc.SetEventObject( child ); - if ( !child->HandleWindowEvent( eventNc ) ) - { - child->MacPaintBorders(0, 0) ; - } + child->MacPaintBorders(0, 0) ; } } } -#endif - return handled ; } @@ -2081,7 +2001,10 @@ void wxWindowMac::MacRepositionScrollBars() bool wxWindowMac::AcceptsFocus() const { - return m_peer->CanFocus() && wxWindowBase::AcceptsFocus(); + if ( MacIsUserPane() ) + return wxWindowBase::AcceptsFocus(); + else + return m_peer->CanFocus(); } void wxWindowMac::MacSuperChangedPosition() @@ -2123,25 +2046,28 @@ long wxWindowMac::MacGetLeftBorderSize() const SInt32 border = 0 ; - if (HasFlag(wxRAISED_BORDER) || HasFlag( wxSUNKEN_BORDER) || HasFlag(wxDOUBLE_BORDER)) + if ( m_peer && m_peer->NeedsFrame() ) { + 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; + // this metric is only the 'outset' outside the simple frame rect + GetThemeMetric( kThemeMetricEditTextFrameOutset , &border ) ; + border += 1; #else - border += 2; + border += 2; #endif - } - else if (HasFlag(wxSIMPLE_BORDER)) - { + } + 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; + // this metric is only the 'outset' outside the simple frame rect + GetThemeMetric( kThemeMetricListBoxFrameOutset , &border ) ; + border += 1; #else - border += 1; + border += 1; #endif + } } return border ; @@ -2216,24 +2142,7 @@ void wxWindowMac::OnMouseEvent( wxMouseEvent &event ) } } -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)) +void wxWindowMac::TriggerScrollEvent( wxEventType WXUNUSED(scrollEvent) ) { } @@ -2247,7 +2156,7 @@ Rect wxMacGetBoundsForControl( wxWindowMac* window , const wxPoint& pos , const return bounds ; } -bool wxWindowMac::HandleClicked( double timestampsec ) +bool wxWindowMac::OSXHandleClicked( double WXUNUSED(timestampsec) ) { return false; } @@ -2255,7 +2164,7 @@ bool wxWindowMac::HandleClicked( double timestampsec ) wxInt32 wxWindowMac::MacControlHit(WXEVENTHANDLERREF WXUNUSED(handler) , WXEVENTREF event ) { #if wxOSX_USE_COCOA_OR_CARBON - if ( HandleClicked( GetEventTime((EventRef)event) ) ) + if ( OSXHandleClicked( GetEventTime((EventRef)event) ) ) return noErr; return eventNotHandledErr ; @@ -2321,10 +2230,103 @@ bool wxWindowMac::IsShownOnScreen() const return wxWindowBase::IsShownOnScreen(); } +bool wxWindowMac::OSXHandleKeyEvent( wxKeyEvent& event ) +{ + bool handled = HandleWindowEvent( event ) ; + if ( handled && event.GetSkipped() ) + handled = false ; + +#if wxUSE_ACCEL + if ( !handled && event.GetEventType() == wxEVT_KEY_DOWN) + { + wxWindow *ancestor = this; + while (ancestor) + { + int command = ancestor->GetAcceleratorTable()->GetCommand( event ); + if (command != -1) + { + wxEvtHandler * const handler = ancestor->GetEventHandler(); + + wxCommandEvent command_event( wxEVT_COMMAND_MENU_SELECTED, command ); + handled = handler->ProcessEvent( command_event ); + + if ( !handled ) + { + // accelerators can also be used with buttons, try them too + command_event.SetEventType(wxEVT_COMMAND_BUTTON_CLICKED); + handled = handler->ProcessEvent( command_event ); + } + + break; + } + + if (ancestor->IsTopLevel()) + break; + + ancestor = ancestor->GetParent(); + } + } +#endif // wxUSE_ACCEL + + return handled ; +} + // // wxWidgetImpl // +WX_DECLARE_HASH_MAP(WXWidget, wxWidgetImpl*, wxPointerHash, wxPointerEqual, MacControlMap); + +static MacControlMap wxWinMacControlList; + +wxWindowMac *wxFindWindowFromWXWidget(WXWidget inControl ) +{ + wxWidgetImpl* impl = wxWidgetImpl::FindFromWXWidget( inControl ); + if ( impl ) + return impl->GetWXPeer(); + + return NULL; +} + +wxWidgetImpl *wxWidgetImpl::FindFromWXWidget(WXWidget inControl ) +{ + MacControlMap::iterator node = wxWinMacControlList.find(inControl); + + return (node == wxWinMacControlList.end()) ? NULL : node->second; +} + +void wxWidgetImpl::Associate(WXWidget inControl, wxWidgetImpl *impl) +{ + // 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 WXWidget to control map") ); + + wxWinMacControlList[inControl] = impl; +} + +void wxWidgetImpl::RemoveAssociations(wxWidgetImpl* impl) +{ + // 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 == impl ) + { + wxWinMacControlList.erase(it); + found = true ; + break; + } + } + } +} + IMPLEMENT_ABSTRACT_CLASS( wxWidgetImpl , wxObject ) wxWidgetImpl::wxWidgetImpl( wxWindowMac* peer , bool isRootControl ) @@ -2348,6 +2350,7 @@ void wxWidgetImpl::Init() m_isRootControl = false; m_wxPeer = NULL; m_needsFocusRect = false; + m_needsFrame = true; } void wxWidgetImpl::SetNeedsFocusRect( bool needs ) @@ -2360,3 +2363,12 @@ bool wxWidgetImpl::NeedsFocusRect() const return m_needsFocusRect; } +void wxWidgetImpl::SetNeedsFrame( bool needs ) +{ + m_needsFrame = needs; +} + +bool wxWidgetImpl::NeedsFrame() const +{ + return m_needsFrame; +}