]> git.saurik.com Git - wxWidgets.git/blobdiff - src/osx/cocoa/toolbar.mm
Applied Blit system options optimization to StretchBlit
[wxWidgets.git] / src / osx / cocoa / toolbar.mm
index f02306785f321da92d4d2cc3bb6db90b62b26731..344f8b7ef4520fc623a0a6ea2e4b8dbef6ceec5e 100644 (file)
@@ -1,10 +1,10 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        src/osx/carbon/toolbar.cpp
+// Name:        src/osx/cocoa/toolbar.mm
 // Purpose:     wxToolBar
 // Author:      Stefan Csomor
 // Modified by:
 // Created:     04/01/98
-// RCS-ID:      $Id: toolbar.cpp 54954 2008-08-03 11:27:03Z VZ $
+// RCS-ID:      $Id$
 // Copyright:   (c) Stefan Csomor
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
@@ -43,6 +43,21 @@ END_EVENT_TABLE()
 // private classes
 // ----------------------------------------------------------------------------
 
+class wxToolBarTool;
+
+@interface wxNSToolBarButton : NSButton
+{
+    wxToolBarTool* impl;
+}
+
+- (id)initWithFrame:(NSRect)frame;
+- (void) clickedAction: (id) sender;
+- (void)setImplementation: (wxToolBarTool *) theImplementation;
+- (wxToolBarTool*) implementation;
+- (BOOL) isFlipped;
+
+@end
+
 // We have a dual implementation for each tool, WXWidget and NSToolbarItem*
 
 // when embedding native controls in the native toolbar we must make sure the
@@ -130,13 +145,15 @@ public:
         }
         else if ( IsButton() )
         {
-            curSize = GetToolBar()->GetToolSize();
+            // curSize = GetToolBar()->GetToolSize();
+            NSRect best = [(wxNSToolBarButton*)m_controlHandle frame];
+            curSize = wxSize(best.size.width, best.size.height);
         }
         else
         {
             // separator size
             curSize = GetToolBar()->GetToolSize();
-            if ( GetToolBar()->GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT) )
+            if ( GetToolBar()->IsVertical() )
                 curSize.y /= 4;
             else
                 curSize.x /= 4;
@@ -150,28 +167,31 @@ public:
         return wxPoint( m_x, m_y );
     }
 
-    bool DoEnable( bool enable );
+    bool Enable( bool enable );
 
     void UpdateImages();
-    
+
     void UpdateToggleImage( bool toggle );
-    
+
     void UpdateLabel()
     {
+        wxString labelStr = wxStripMenuCodes(m_label);
+        wxCFStringRef l(labelStr, GetToolBarFontEncoding());
+        wxCFStringRef sh( GetShortHelp(), GetToolBarFontEncoding() );
 #if wxOSX_USE_NATIVE_TOOLBAR
        if ( m_toolbarItem )
         {
             // strip mnemonics from the label for compatibility with the usual
             // labels in wxStaticText sense
-            wxString labelStr = wxStripMenuCodes(m_label);
-            wxCFStringRef l(labelStr, GetToolBarFontEncoding());
 
             [m_toolbarItem setLabel:l.AsNSString()];
-            
-            wxCFStringRef sh( GetShortHelp(), GetToolBarFontEncoding() );
+
             [m_toolbarItem setToolTip:sh.AsNSString()];
         }
 #endif
+        if ( IsButton() )
+            [(NSButton*)m_controlHandle setTitle:l.AsNSString()];
+
     }
 
     void Action()
@@ -187,7 +207,7 @@ public:
 
         tbar->OnLeftClick( GetId(), IsToggled() );
     }
-    
+
 #if wxOSX_USE_NATIVE_TOOLBAR
     void SetToolbarItemRef( NSToolbarItem* ref )
     {
@@ -218,7 +238,17 @@ public:
     {
         wxToolBarToolBase::SetLabel(label);
         UpdateLabel();
-     }
+    }
+
+    virtual bool SetShortHelp(const wxString& help)
+    {
+        if ( !wxToolBarToolBase::SetShortHelp(help) )
+            return false;
+
+        UpdateLabel();
+
+        return true;
+    }
 #endif // wxOSX_USE_NATIVE_TOOLBAR
 
 private:
@@ -265,16 +295,17 @@ private:
 - (void)setImplementation: (wxToolBarTool *) theImplementation;
 - (wxToolBarTool*) implementation;
 - (void) clickedAction: (id) sender;
+- (BOOL) validateToolbarItem:(NSToolbarItem *)theItem;
 
 @end
 
 
-@interface wxNSToolbarDelegate : NSObject
+@interface wxNSToolbarDelegate : NSObject wxOSX_10_6_AND_LATER(<NSToolbarDelegate>)
 {
 }
 
 - (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag;
-    
+
 - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar;
 
 - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar;
@@ -287,26 +318,13 @@ private:
 #endif
 
 
-@interface wxNSToolBarButton : NSButton
-{
-    wxToolBarTool* impl;
-}
-
-- (id)initWithFrame:(NSRect)frame;
-- (void) clickedAction: (id) sender;
-- (void)setImplementation: (wxToolBarTool *) theImplementation;
-- (wxToolBarTool*) implementation;
-- (BOOL) isFlipped;
-
-@end
-
 #if wxOSX_USE_NATIVE_TOOLBAR
 
 @implementation wxNSToolbarItem
 
 - (id)initWithItemIdentifier: (NSString*) identifier
 {
-    [super initWithItemIdentifier:identifier];
+    self = [super initWithItemIdentifier:identifier];
     impl = NULL;
     [self setTarget: self];
     [self setAction: @selector(clickedAction:)];
@@ -332,6 +350,12 @@ private:
     return impl;
 }
 
+- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
+{
+    wxUnusedVar(theItem);
+    return impl->IsEnabled() ? YES:NO;
+}
+
 @end
 
 @implementation wxNSToolbarDelegate
@@ -389,7 +413,7 @@ private:
 
 - (id)initWithFrame:(NSRect)frame
 {
-    [super initWithFrame:frame];
+    self = [super initWithFrame:frame];
     impl = NULL;
     [self setTarget: self];
     [self setAction: @selector(clickedAction:)];
@@ -422,8 +446,11 @@ private:
 
 @end
 
-bool wxToolBarTool::DoEnable( bool enable )
+bool wxToolBarTool::Enable( bool enable )
 {
+    if ( wxToolBarToolBase::Enable( enable ) == false )
+        return false;
+
     if ( IsControl() )
     {
         GetControl()->Enable( enable );
@@ -479,7 +506,7 @@ void wxToolBarTool::SetPosition( const wxPoint& position )
             frame.origin.y = mac_y;
             [m_controlHandle setFrame:frame];
         }
-    }    
+    }
 }
 
 void wxToolBarTool::UpdateImages()
@@ -496,10 +523,10 @@ void wxToolBarTool::UpdateImages()
         dc.SelectObject( m_alternateBitmap );
         dc.SetPen( wxPen(*wxBLACK) );
         dc.SetBrush( wxBrush( *wxLIGHT_GREY ));
-        dc.DrawRectangle( 0, 0, w, h );
+        dc.DrawRoundedRectangle( 0, 0, w, h, 2 );
         dc.DrawBitmap( m_bmpNormal, 0, 0, true );
         dc.SelectObject( wxNullBitmap );
-        
+
         [(NSButton*) m_controlHandle setAlternateImage:m_alternateBitmap.GetNSImage()];
     }
     UpdateToggleImage( CanBeToggled() && IsToggled() );
@@ -517,7 +544,12 @@ void wxToolBarTool::UpdateToggleImage( bool toggle )
         else
             [m_toolbarItem setImage:m_bmpNormal.GetNSImage()];
     }
+    else
 #endif
+    {
+        if ( IsButton() )
+            [(NSButton*)m_controlHandle setState:(toggle ? NSOnState : NSOffState)];
+    }
 }
 
 wxToolBarTool::wxToolBarTool(
@@ -598,19 +630,19 @@ bool wxToolBar::Create(
     if (parent->IsKindOf(CLASSINFO(wxFrame)) && wxSystemOptions::GetOptionInt(wxT("mac.toolbar.no-native")) != 1)
     {
         static wxNSToolbarDelegate* controller = nil;
-        
+
         if ( controller == nil )
             controller = [[wxNSToolbarDelegate alloc] init];
         wxString identifier = wxString::Format( wxT("%p"), this );
         wxCFStringRef cfidentifier(identifier);
         NSToolbar* tb =  [[NSToolbar alloc] initWithIdentifier:cfidentifier.AsNSString()];
-        
+
         m_macToolbar = tb ;
-        
+
         if (m_macToolbar != NULL)
         {
             [tb setDelegate:controller];
-            
+
             NSToolbarDisplayMode mode = NSToolbarDisplayModeDefault;
             NSToolbarSizeMode displaySize = NSToolbarSizeModeSmall;
 
@@ -631,19 +663,17 @@ bool wxToolBar::Create(
 }
 
 wxToolBar::~wxToolBar()
-{
-#if wxOSX_USE_NATIVE_TOOLBAR
-    if (m_macToolbar != NULL)
+{  
+    // removal only works while the toolbar is there
+    wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
+    if ( frame && frame->GetToolBar() == this )
     {
-        // if this is the installed toolbar, then deinstall it
-        if (m_macUsesNativeToolbar)
-            MacInstallNativeToolbar( false );
-
-        [(NSToolbar*)m_macToolbar setDelegate:nil];
-        [(NSToolbar*)m_macToolbar release];
-        m_macToolbar = NULL;
+        frame->SetToolBar(NULL);
     }
-#endif
+    
+    [(NSToolbar*)m_macToolbar setDelegate:nil];
+    [(NSToolbar*)m_macToolbar release];
+    m_macToolbar = NULL;
 }
 
 bool wxToolBar::Show( bool show )
@@ -706,7 +736,7 @@ void wxToolBar::DoGetSize( int *width, int *height ) const
         WXWindow tlw = MacGetTopLevelWindowRef();
         float toolbarHeight = 0.0;
         NSRect windowFrame = NSMakeRect(0, 0, 0, 0);
+
         if(m_macToolbar && [(NSToolbar*)m_macToolbar isVisible])
         {
             windowFrame = [NSWindow contentRectForFrameRect:[tlw frame]
@@ -714,7 +744,7 @@ void wxToolBar::DoGetSize( int *width, int *height ) const
             toolbarHeight = NSHeight(windowFrame)
                         - NSHeight([[tlw contentView] frame]);
         }
+
         if ( width != NULL )
             *width = (int)windowFrame.size.width;
         if ( height != NULL )
@@ -730,11 +760,11 @@ void wxToolBar::DoGetSize( int *width, int *height ) const
 
 wxSize wxToolBar::DoGetBestSize() const
 {
-    int width, height;
-
-    DoGetSize( &width, &height );
+    // was updated in Realize()
+    
+    wxSize size = GetMinSize();
 
-    return wxSize( width, height );
+    return size;
 }
 
 void wxToolBar::SetWindowStyleFlag( long style )
@@ -790,7 +820,7 @@ bool wxToolBar::MacInstallNativeToolbar(bool usesNative)
     if (usesNative && (m_macToolbar == NULL))
         return bResult;
 
-    if (usesNative && ((GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT|wxTB_BOTTOM)) != 0))
+    if (usesNative && HasFlag(wxTB_LEFT|wxTB_RIGHT|wxTB_BOTTOM) )
         return bResult;
 
     WXWindow tlw = MacGetTopLevelWindowRef();
@@ -810,10 +840,10 @@ bool wxToolBar::MacInstallNativeToolbar(bool usesNative)
             bResult = true;
             [tlw setToolbar:(NSToolbar*) m_macToolbar];
             [(NSToolbar*) m_macToolbar setVisible:YES];
-            
-            m_peer->Move(0,0,0,0 );
+
+            GetPeer()->Move(0,0,0,0 );
             SetSize( wxSIZE_AUTO_WIDTH, 0 );
-            m_peer->SetVisibility( false );
+            GetPeer()->SetVisibility( false );
             wxToolBarBase::Show( false );
         }
     }
@@ -824,8 +854,8 @@ bool wxToolBar::MacInstallNativeToolbar(bool usesNative)
         {
             bResult = true;
             [(NSToolbar*) m_macToolbar setVisible:NO];
-            [tlw setToolbar:nil];
-            m_peer->SetVisibility( true );
+            MacUninstallNativeToolbar();
+            GetPeer()->SetVisibility( true );
         }
     }
 
@@ -835,26 +865,29 @@ bool wxToolBar::MacInstallNativeToolbar(bool usesNative)
 // wxLogDebug( wxT("    --> [%lx] - result [%s]"), (long)this, bResult ? wxT("T") : wxT("F") );
     return bResult;
 }
-#endif
 
-bool wxToolBar::Realize()
+void wxToolBar::MacUninstallNativeToolbar()
 {
-    if (m_tools.GetCount() == 0)
-        return false;
-
-    int maxWidth = 0;
-    int maxHeight = 0;
+    if (!m_macToolbar)
+        return;
+        
+    WXWindow tlw = MacGetTopLevelWindowRef();
+    if (tlw)
+        [tlw setToolbar:nil];
+}
+#endif
 
+void wxToolBar::DoLayout()
+{
     int maxToolWidth = 0;
     int maxToolHeight = 0;
-
-    int x = m_xMargin + kwxMacToolBarLeftMargin;
-    int y = m_yMargin + kwxMacToolBarTopMargin;
-
+    
     int tw, th;
     GetSize( &tw, &th );
-
+    
     // find the maximum tool width and height
+    // and the number of stretchable items
+    int numStretchableSpaces = 0;
     wxToolBarTool *tool;
     wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
     while ( node )
@@ -863,33 +896,28 @@ bool wxToolBar::Realize()
         if ( tool != NULL )
         {
             wxSize  sz = tool->GetSize();
-
+            
             if ( sz.x > maxToolWidth )
                 maxToolWidth = sz.x;
             if ( sz.y > maxToolHeight )
                 maxToolHeight = sz.y;
+            if ( tool->IsStretchableSpace() )
+                numStretchableSpaces++;
         }
-
+        
         node = node->GetNext();
     }
 
-    bool lastIsRadio = false;
-    bool curIsRadio = false;
-
-#if wxOSX_USE_NATIVE_TOOLBAR
-    CFIndex currentPosition = 0;
-    bool insertAll = false;
-
-    NSToolbar* refTB = (NSToolbar*)m_macToolbar;
-    wxFont f;
-    wxFontEncoding enc;
-    f = GetFont();
-    if ( f.IsOk() )
-        enc = f.GetEncoding();
-    else
-        enc = wxFont::GetDefaultEncoding();
-#endif
-
+    // layout non-native toolbar 
+    
+    bool isHorizontal =  !IsVertical();
+    
+    int maxWidth = 0;
+    int maxHeight = 0;
+    
+    int x = m_xMargin + kwxMacToolBarLeftMargin;
+    int y = m_yMargin + kwxMacToolBarTopMargin;
+    
     node = m_tools.GetFirst();
     while ( node )
     {
@@ -899,7 +927,7 @@ bool wxToolBar::Realize()
             node = node->GetNext();
             continue;
         }
-
+        
         // set tool position:
         // for the moment just perform a single row/column alignment
         wxSize  cursize = tool->GetSize();
@@ -907,8 +935,80 @@ bool wxToolBar::Realize()
             maxWidth = x + cursize.x;
         if ( y + cursize.y > maxHeight )
             maxHeight = y + cursize.y;
-
-        if ( GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT) )
+        
+        // update the item positioning state
+        if ( !isHorizontal )
+            y += cursize.y + kwxMacToolSpacing;
+        else
+            x += cursize.x + kwxMacToolSpacing;
+        
+        node = node->GetNext();
+    }
+    
+    if ( isHorizontal )
+    {
+        // if not set yet, only one row
+        if ( m_maxRows <= 0 )
+            SetRows( 1 );
+        
+        maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
+        m_minWidth = maxWidth;
+        m_minHeight = m_maxHeight = maxToolHeight + 2 * (m_yMargin + kwxMacToolBarTopMargin);
+    }
+    else
+    {
+        // if not set yet, have one column
+        if ( (GetToolsCount() > 0) && (m_maxRows <= 0) )
+            SetRows( GetToolsCount() );
+        
+        maxHeight += m_yMargin + kwxMacToolBarTopMargin;
+        m_minHeight = maxHeight;
+        m_minWidth = m_maxWidth = maxToolWidth + 2 * (m_yMargin + kwxMacToolBarTopMargin);
+    }
+    
+    int totalStretchableSpace = 0;
+    int spacePerStretchable = 0;
+    if ( numStretchableSpaces > 0 )
+    {
+        if ( isHorizontal )
+            totalStretchableSpace = tw - maxWidth;
+        else
+            totalStretchableSpace = th - maxHeight;
+        
+        if ( totalStretchableSpace > 0 )
+            spacePerStretchable = totalStretchableSpace / numStretchableSpaces;            
+    }
+    
+    // perform real positioning
+    
+    x = m_xMargin + kwxMacToolBarLeftMargin;
+    y = m_yMargin + kwxMacToolBarTopMargin;
+    
+    node = m_tools.GetFirst();
+    int currentStretchable = 0;
+    while ( node )
+    {
+        tool = (wxToolBarTool*) node->GetData();
+        if ( tool == NULL )
+        {
+            node = node->GetNext();
+            continue;
+        }
+        
+        wxSize  cursize = tool->GetSize();
+        if ( tool->IsStretchableSpace() )
+        {
+            ++currentStretchable;
+            int thisSpace = currentStretchable == numStretchableSpaces ? 
+            totalStretchableSpace - (currentStretchable-1)*spacePerStretchable :
+            spacePerStretchable;
+            if ( isHorizontal )
+                cursize.x += thisSpace;
+            else 
+                cursize.y += thisSpace;
+        }
+        
+        if ( !isHorizontal )
         {
             int x1 = x + ( maxToolWidth - cursize.x ) / 2;
             tool->SetPosition( wxPoint(x1, y) );
@@ -918,14 +1018,49 @@ bool wxToolBar::Realize()
             int y1 = y + ( maxToolHeight - cursize.y ) / 2;
             tool->SetPosition( wxPoint(x, y1) );
         }
-
+        
         // update the item positioning state
-        if ( GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT) )
+        if ( !isHorizontal )
             y += cursize.y + kwxMacToolSpacing;
         else
             x += cursize.x + kwxMacToolSpacing;
+        
+        node = node->GetNext();
+    }
+    
+}
+
+bool wxToolBar::Realize()
+{
+    if ( !wxToolBarBase::Realize() )
+        return false;
+
+    wxToolBarTool *tool;
+    wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
 
 #if wxOSX_USE_NATIVE_TOOLBAR
+    CFIndex currentPosition = 0;
+    bool insertAll = false;
+
+    NSToolbar* refTB = (NSToolbar*)m_macToolbar;
+    wxFont f;
+    wxFontEncoding enc;
+    f = GetFont();
+    if ( f.IsOk() )
+        enc = f.GetEncoding();
+    else
+        enc = wxFont::GetDefaultEncoding();
+
+    node = m_tools.GetFirst();
+    while ( node )
+    {
+        tool = (wxToolBarTool*) node->GetData();
+        if ( tool == NULL )
+        {
+            node = node->GetNext();
+            continue;
+        }
+                
         // install in native NSToolbar
         if ( refTB )
         {
@@ -936,22 +1071,22 @@ bool wxToolBar::Realize()
                 // the strings now
                 wxCFStringRef sh( tool->GetShortHelp(), enc);
                 [hiItemRef setToolTip:sh.AsNSString()];
-
+                
                 if ( insertAll || (tool->GetIndex() != currentPosition) )
                 {
                     if ( !insertAll )
                     {
                         insertAll = true;
-
+                        
                         // if this is the first tool that gets newly inserted or repositioned
                         // first remove all 'old' tools from here to the right, because of this
                         // all following tools will have to be reinserted (insertAll).
                         for ( wxToolBarToolsList::compatibility_iterator node2 = m_tools.GetLast();
-                              node2 != node;
-                              node2 = node2->GetPrevious() )
+                             node2 != node;
+                             node2 = node2->GetPrevious() )
                         {
                             wxToolBarTool *tool2 = (wxToolBarTool*) node2->GetData();
-
+                            
                             const long idx = tool2->GetIndex();
                             if ( idx != -1 )
                             {
@@ -960,18 +1095,49 @@ bool wxToolBar::Realize()
                             }
                         }
                     }
-                    wxString identifier = wxString::Format( wxT("%ld"), (long) tool );
-                    wxCFStringRef cfidentifier(identifier);
-
-                    [refTB insertItemWithItemIdentifier:cfidentifier.AsNSString() atIndex:currentPosition];
+                    
+                    wxCFStringRef cfidentifier;
+                    NSString *nsItemId;
+                    if (tool->GetStyle() == wxTOOL_STYLE_SEPARATOR)
+                    {
+                        nsItemId = tool->IsStretchable() ? NSToolbarFlexibleSpaceItemIdentifier
+                        : NSToolbarSeparatorItemIdentifier;
+                    }
+                    else
+                    {
+                        cfidentifier = wxCFStringRef(wxString::Format("%ld", (long)tool));
+                        nsItemId = cfidentifier.AsNSString();
+                    }
+                    
+                    [refTB insertItemWithItemIdentifier:nsItemId atIndex:currentPosition];
                     tool->SetIndex( currentPosition );
                 }
-
+                
                 currentPosition++;
             }
         }
+        node = node->GetNext();
+    }
+    
 #endif
-
+    
+    DoLayout();
+    
+    // adjust radio items
+        
+    bool lastIsRadio = false;
+    bool curIsRadio = false;
+    
+    node = m_tools.GetFirst();
+    while ( node )
+    {
+        tool = (wxToolBarTool*) node->GetData();
+        if ( tool == NULL )
+        {
+            node = node->GetNext();
+            continue;
+        }
+            
         // update radio button (and group) state
         lastIsRadio = curIsRadio;
         curIsRadio = ( tool->IsButton() && (tool->GetKind() == wxITEM_RADIO) );
@@ -1013,54 +1179,21 @@ bool wxToolBar::Realize()
         node = node->GetNext();
     }
 
-    if ( GetWindowStyleFlag() & (wxTB_TOP|wxTB_BOTTOM) )
-    {
-        // if not set yet, only one row
-        if ( m_maxRows <= 0 )
-            SetRows( 1 );
-
-        m_minWidth = maxWidth;
-        // maxHeight = th;
-        maxHeight += m_yMargin + kwxMacToolBarTopMargin;
-        m_minHeight = m_maxHeight = maxHeight;
-    }
-    else
-    {
-        // if not set yet, have one column
-        if ( (GetToolsCount() > 0) && (m_maxRows <= 0) )
-            SetRows( GetToolsCount() );
-
-        m_minHeight = maxHeight;
-        // maxWidth = tw;
-        maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
-        m_minWidth = m_maxWidth = maxWidth;
-    }
-
-#if 0
-    // FIXME: should this be OSX-only?
-    {
-        bool wantNativeToolbar, ownToolbarInstalled;
-
-        // attempt to install the native toolbar
-        wantNativeToolbar = ((GetWindowStyleFlag() & (wxTB_LEFT|wxTB_BOTTOM|wxTB_RIGHT)) == 0);
-        MacInstallNativeToolbar( wantNativeToolbar );
-        (void)MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
-        if (!ownToolbarInstalled)
-        {
-           SetSize( maxWidth, maxHeight );
-           InvalidateBestSize();
-        }
-    }
-#else
-    SetSize( maxWidth, maxHeight );
     InvalidateBestSize();
-#endif
-
-    SetInitialSize();
+    SetInitialSize( wxSize(m_minWidth, m_minHeight));
 
+    SendSizeEventToParent();
+    
     return true;
 }
 
+void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+{
+    wxToolBarBase::DoSetSize(x, y, width, height, sizeFlags);
+    
+    DoLayout();
+}    
+
 void wxToolBar::SetToolBitmapSize(const wxSize& size)
 {
     m_defaultWidth = size.x + kwxMacToolBorder;
@@ -1100,6 +1233,7 @@ void wxToolBar::MacSuperChangedPosition()
 {
     wxWindow::MacSuperChangedPosition();
 
+    /*
 #if wxOSX_USE_NATIVE_TOOLBAR
     if (! m_macUsesNativeToolbar )
         Realize();
@@ -1107,6 +1241,7 @@ void wxToolBar::MacSuperChangedPosition()
 
     Realize();
 #endif
+     */
 }
 
 void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap )
@@ -1165,10 +1300,9 @@ wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
     return wxEmptyString;
 }
 
-void wxToolBar::DoEnableTool(wxToolBarToolBase *t, bool enable)
+void wxToolBar::DoEnableTool(wxToolBarToolBase * WXUNUSED(t), bool WXUNUSED(enable))
 {
-    if ( t != NULL )
-        ((wxToolBarTool*)t)->DoEnable( enable );
+    // everything already done in the tool's Enable implementation
 }
 
 void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
@@ -1184,6 +1318,8 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
     if (tool == NULL)
         return false;
 
+    long style = GetWindowStyleFlag();
+    
     wxSize toolSize = GetToolSize();
     WXWidget controlHandle = NULL;
     NSRect toolrect = NSMakeRect(0, 0, toolSize.x, toolSize.y );
@@ -1205,7 +1341,7 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
                 wxASSERT( tool->GetControlHandle() == NULL );
                 toolSize.x /= 4;
                 toolSize.y /= 4;
-                if ( GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT) )
+                if ( IsVertical() )
                     toolrect.size.height = toolSize.y;
                 else
                     toolrect.size.width = toolSize.x;
@@ -1214,7 +1350,9 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
 #if wxOSX_USE_NATIVE_TOOLBAR
                 if (m_macToolbar != NULL)
                 {
-                    NSToolbarItem* item = [[NSToolbarItem alloc] initWithItemIdentifier:NSToolbarSeparatorItemIdentifier];
+                    NSString * nsItemId = tool->IsStretchable() ? NSToolbarFlexibleSpaceItemIdentifier
+                                                         : NSToolbarSeparatorItemIdentifier;
+                    NSToolbarItem* item = [[NSToolbarItem alloc] initWithItemIdentifier:nsItemId];
                     tool->SetToolbarItemRef( item );
                 }
 #endif // wxOSX_USE_NATIVE_TOOLBAR
@@ -1234,11 +1372,11 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
 
                 [v setBezelStyle:NSRegularSquareBezelStyle];
                 [v setBordered:NO];
-                [v setButtonType: ( tool->CanBeToggled() ? NSOnOffButton : NSMomentaryPushInButton )];
+                [v setButtonType: ( tool->CanBeToggled() ? NSToggleButton : NSMomentaryPushInButton )];
                 [v setImplementation:tool];
                 
                 controlHandle = v;
-                
+
 #if wxOSX_USE_NATIVE_TOOLBAR
                 if (m_macToolbar != NULL)
                 {
@@ -1253,10 +1391,15 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
                 tool->SetControlHandle( controlHandle );
                 tool->UpdateImages();
                 tool->UpdateLabel();
-#if 0
-                SetBevelButtonTextPlacement( m_controlHandle, kControlBevelButtonPlaceBelowGraphic );
-                SetControlTitleWithCFString( m_controlHandle , wxCFStringRef( label, wxFont::GetDefaultEncoding() );
-#endif
+
+                if ( style & wxTB_NOICONS )
+                    [v setImagePosition:NSNoImage];
+                else if ( style & wxTB_TEXT )
+                    [v setImagePosition:NSImageAbove];
+                else
+                    [v setImagePosition:NSImageOnly];
+                [v sizeToFit];
+                
 #if 0
                 InstallControlEventHandler(
                     (WXWidget) controlHandle, GetwxMacToolBarToolEventHandlerUPP(),
@@ -1271,7 +1414,7 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
             if (m_macToolbar != NULL)
             {
                 WXWidget view = (WXWidget) tool->GetControl()->GetHandle() ;
-                wxCHECK_MSG( view, false, _T("control must be non-NULL") );
+                wxCHECK_MSG( view, false, wxT("control must be non-NULL") );
 
                 wxString identifier = wxString::Format(wxT("%ld"), (long) tool);
                 wxCFStringRef cfidentifier( identifier, wxFont::GetDefaultEncoding() );
@@ -1352,7 +1495,7 @@ bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolbase)
         wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
         wxPoint pt = tool2->GetPosition();
 
-        if ( GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT) )
+        if ( IsVertical() )
             pt.y -= sz.y;
         else
             pt.x -= sz.x;
@@ -1380,34 +1523,52 @@ void wxToolBar::OnPaint(wxPaintEvent& event)
 #if wxOSX_USE_NATIVE_TOOLBAR
     if ( m_macUsesNativeToolbar )
     {
-        event.Skip(true);
-        return;
+        // nothing to do here
     }
+    else
 #endif
+    {
+        int w, h;
+        GetSize( &w, &h );
 
-    wxPaintDC dc(this);
-
-    int w, h;
-    GetSize( &w, &h );
-
-    bool drawMetalTheme = MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL;
+        bool drawMetalTheme = MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL;
 
-    if ( !drawMetalTheme  )
-    {
-        HIThemePlacardDrawInfo info;
-        memset( &info, 0, sizeof(info) );
-        info.version = 0;
-        info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive;
-
-        CGContextRef cgContext = (CGContextRef) MacGetCGContextRef();
-        HIRect rect = CGRectMake( 0, 0, w, h );
-        HIThemeDrawPlacard( &rect, &info, cgContext, kHIThemeOrientationNormal );
-    }
-    else
-    {
-        // leave the background as it is (striped or metal)
+        if ( UMAGetSystemVersion() < 0x1050 )
+        {
+            if ( !drawMetalTheme )
+            {
+                HIThemePlacardDrawInfo info;
+                memset( &info, 0, sizeof(info) );
+                info.version = 0;
+                info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive;
+
+                CGContextRef cgContext = (CGContextRef) MacGetCGContextRef();
+                HIRect rect = CGRectMake( 0, 0, w, h );
+                HIThemeDrawPlacard( &rect, &info, cgContext, kHIThemeOrientationNormal );
+            }
+            else
+            {
+                // leave the background as it is (striped or metal)
+            }
+        }
+        else
+        {
+            wxPaintDC dc(this);
+            
+            wxRect rect(0,0,w,h);
+            
+            dc.GradientFillLinear( rect , wxColour( 0xCC,0xCC,0xCC ), wxColour( 0xA8,0xA8,0xA8 ) , wxSOUTH );
+            dc.SetPen( wxPen( wxColour( 0x51,0x51,0x51 ) ) );
+            if ( HasFlag(wxTB_LEFT) )
+                dc.DrawLine(w-1, 0, w-1, h);
+            else if ( HasFlag(wxTB_RIGHT) )
+                dc.DrawLine(0, 0, 0, h);
+            else if ( HasFlag(wxTB_BOTTOM) )
+                dc.DrawLine(0, 0, w, 0);
+            else if ( HasFlag(wxTB_TOP) )
+                dc.DrawLine(0, h-1, w, h-1);
+        }
     }
-
     event.Skip();
 }