]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/window_osx.cpp
implement SetTimes() for directories too under MSW (#10250)
[wxWidgets.git] / src / osx / window_osx.cpp
index 24c45ddb07696afebc6c2cac84a35a574eeb383d..ac75853aa46d6af9ea02f672b1cf25e130132682 100644 (file)
@@ -61,6 +61,8 @@
 #include "wx/dnd.h"
 #endif
 
+#include "wx/graphics.h"
+
 #if wxOSX_USE_CARBON
 #include "wx/osx/uma.h"
 #else
@@ -272,19 +274,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 +286,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,11 +305,43 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
         return;
 
     m_peer->SetControlSize( variant );
+#if wxOSX_USE_CARBON
+    ControlSize size ;
+
+    // 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;
+            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 ;
+    }
+    m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
+#endif
+
 #if wxOSX_USE_COCOA_OR_CARBON
     wxFont font ;
 
-#if wxOSX_USE_CARBON
-    ControlSize size ;
+#if wxOSX_USE_ATSU_TEXT
     ThemeFontID themeFont = kThemeSystemFont ;
 
     // we will get that from the settings later
@@ -324,23 +351,19 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
     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 ;
 
@@ -349,7 +372,6 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
             break ;
     }
 
-    m_peer->SetData<ControlSize>(kControlEntireControl, kControlSizeTag, &size ) ;
     font.MacCreateFromThemeFont( themeFont ) ;
 #else
     CTFontUIFontType themeFont = kCTFontSystemFontType ;
@@ -384,9 +406,9 @@ void wxWindowMac::DoSetWindowVariant( wxWindowVariant variant )
 
 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() ;
@@ -453,8 +475,7 @@ void wxWindowMac::DoReleaseMouse()
 
 void wxWindowMac::SetDropTarget(wxDropTarget *pDropTarget)
 {
-    if ( m_dropTarget != NULL )
-        delete m_dropTarget;
+    delete m_dropTarget;
 
     m_dropTarget = pDropTarget;
     if ( m_dropTarget != NULL )
@@ -483,9 +504,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 +516,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 +674,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() ;
@@ -755,32 +775,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->GetPeer()->PopUp(this, x, y);
     menu->SetInvokingWindow( NULL );
-#else
-    menu->SetInvokingWindow( NULL );
-    return false;
-#endif
-
     return true;
 #else
     // actually this shouldn't be called, because universal is having its own implementation
@@ -836,10 +832,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)
@@ -889,9 +887,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() ;
@@ -1134,19 +1132,21 @@ 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,
+void wxWindowMac::GetTextExtent(const wxString& str, int *x, int *y,
                            int *descent, int *externalLeading, const wxFont *theFont ) const
 {
     const wxFont *fontToUse = theFont;
@@ -1157,17 +1157,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);
 }
 
 /*
@@ -1861,9 +1866,9 @@ bool wxWindowMac::MacDoRedraw( void* updatergnr , long time )
             // the grow-box area of a scrolled window (scroll sample)
             wxDC* dc = new wxWindowDC(this);
             if ( IsTopLevel() )
-                dc->SetClippingRegion(wxRegion(HIShapeCreateWithQDRgn(updatergn)));
+                dc->SetDeviceClippingRegion(wxRegion(HIShapeCreateWithQDRgn(updatergn)));
             else
-                dc->SetClippingRegion(wxRegion(HIShapeCreateWithQDRgn(newupdate)));
+                dc->SetDeviceClippingRegion(wxRegion(HIShapeCreateWithQDRgn(newupdate)));
 
             wxEraseEvent eevent( GetId(), dc );
             eevent.SetEventObject( this );
@@ -2325,6 +2330,58 @@ bool wxWindowMac::IsShownOnScreen() const
 // 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 )