]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/toolbar.cpp
Update wxWebFileHandler to handle paths with fragments correctly, some backends pass...
[wxWidgets.git] / src / univ / toolbar.cpp
index 1745a900fd93144c277f0a39396cf38a967a9a0c..da03781e9c06d6d37a9341225c66bdce9fc7dd03 100644 (file)
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
-    #pragma implementation "univtoolbar.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 
 #if wxUSE_TOOLBAR
 
 
 #if wxUSE_TOOLBAR
 
+#include "wx/toolbar.h"
+
 #ifndef WX_PRECOMP
     #include "wx/utils.h"
     #include "wx/app.h"
 #ifndef WX_PRECOMP
     #include "wx/utils.h"
     #include "wx/app.h"
+    #include "wx/log.h"
+    #include "wx/frame.h"
+    #include "wx/dc.h"
+    #include "wx/image.h"
 #endif
 
 #include "wx/univ/renderer.h"
 
 #endif
 
 #include "wx/univ/renderer.h"
 
-#include "wx/toolbar.h"
-#include "wx/image.h"
-#include "wx/log.h"
+// ----------------------------------------------------------------------------
+// wxStdToolbarInputHandler: translates SPACE and ENTER keys and the left mouse
+// click into button press/release actions
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxStdToolbarInputHandler : public wxStdInputHandler
+{
+public:
+    wxStdToolbarInputHandler(wxInputHandler *inphand);
+
+    virtual bool HandleKey(wxInputConsumer *consumer,
+                           const wxKeyEvent& event,
+                           bool pressed);
+    virtual bool HandleMouse(wxInputConsumer *consumer,
+                             const wxMouseEvent& event);
+    virtual bool HandleMouseMove(wxInputConsumer *consumer, const wxMouseEvent& event);
+    virtual bool HandleFocus(wxInputConsumer *consumer, const wxFocusEvent& event);
+    virtual bool HandleActivation(wxInputConsumer *consumer, bool activated);
+
+private:
+    wxWindow            *m_winCapture;
+    wxToolBarToolBase   *m_toolCapture;
+    wxToolBarToolBase   *m_toolLast;
+};
 
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
 
 // value meaning that m_widthSeparator is not initialized
 
 // ----------------------------------------------------------------------------
 // constants
 // ----------------------------------------------------------------------------
 
 // value meaning that m_widthSeparator is not initialized
-static const wxCoord INVALID_WIDTH = -1;
+static const wxCoord INVALID_WIDTH = wxDefaultCoord;
 
 // ----------------------------------------------------------------------------
 // wxToolBarTool: our implementation of wxToolBarToolBase
 
 // ----------------------------------------------------------------------------
 // wxToolBarTool: our implementation of wxToolBarToolBase
@@ -70,13 +93,31 @@ public:
     {
         // no position yet
         m_x =
     {
         // no position yet
         m_x =
-        m_y = -1;
+        m_y = wxDefaultCoord;
+        m_width =
+        m_height = 0;
 
         // not pressed yet
 
         // not pressed yet
-        m_isInverted = FALSE;
-        
+        m_isInverted = false;
+
         // mouse not here yet
         // mouse not here yet
-        m_underMouse = FALSE;
+        m_underMouse = false;
+    }
+
+    wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label)
+        : wxToolBarToolBase(tbar, control, label)
+    {
+        // no position yet
+        m_x =
+        m_y = wxDefaultCoord;
+        m_width =
+        m_height = 0;
+
+        // not pressed yet
+        m_isInverted = false;
+
+        // mouse not here yet
+        m_underMouse = false;
     }
 
     // is this tool pressed, even temporarily? (this is different from being
     }
 
     // is this tool pressed, even temporarily? (this is different from being
@@ -89,21 +130,23 @@ public:
 
     // press the tool temporarily by inverting its toggle state
     void Invert() { m_isInverted = !m_isInverted; }
 
     // press the tool temporarily by inverting its toggle state
     void Invert() { m_isInverted = !m_isInverted; }
-    
+
     // Set underMouse
     // Set underMouse
-    void SetUnderMouse( bool under = TRUE ) { m_underMouse = under; }
+    void SetUnderMouse( bool under = true ) { m_underMouse = under; }
     bool IsUnderMouse() { return m_underMouse; }
 
 public:
     bool IsUnderMouse() { return m_underMouse; }
 
 public:
-    // the tool position (the size is known by the toolbar itself)
-    int m_x,
-        m_y;
+    // the tool position (for controls)
+    wxCoord m_x;
+    wxCoord m_y;
+    wxCoord m_width;
+    wxCoord m_height;
 
 private:
 
 private:
-    // TRUE if the tool is pressed
+    // true if the tool is pressed
     bool m_isInverted;
     bool m_isInverted;
-    
-    // TRUE if the tool is under the mouse
+
+    // true if the tool is under the mouse
     bool m_underMouse;
 };
 
     bool m_underMouse;
 };
 
@@ -111,7 +154,7 @@ private:
 // wxToolBar implementation
 // ============================================================================
 
 // wxToolBar implementation
 // ============================================================================
 
-IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl);
+IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
 
 // ----------------------------------------------------------------------------
 // wxToolBar creation
 
 // ----------------------------------------------------------------------------
 // wxToolBar creation
@@ -120,7 +163,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl);
 void wxToolBar::Init()
 {
     // no tools yet
 void wxToolBar::Init()
 {
     // no tools yet
-    m_needsLayout = FALSE;
+    m_needsLayout = false;
 
     // unknown widths for the tools and separators
     m_widthSeparator = INVALID_WIDTH;
 
     // unknown widths for the tools and separators
     m_widthSeparator = INVALID_WIDTH;
@@ -144,18 +187,22 @@ bool wxToolBar::Create(wxWindow *parent,
     if ( !wxToolBarBase::Create(parent, id, pos, size, style,
                                 wxDefaultValidator, name) )
     {
     if ( !wxToolBarBase::Create(parent, id, pos, size, style,
                                 wxDefaultValidator, name) )
     {
-        return FALSE;
+        return false;
     }
 
     }
 
+    FixupStyle();
+
     CreateInputHandler(wxINP_HANDLER_TOOLBAR);
 
     CreateInputHandler(wxINP_HANDLER_TOOLBAR);
 
-    SetBestSize(size);
+    SetInitialSize(size);
 
 
-    return TRUE;
+    return true;
 }
 
 wxToolBar::~wxToolBar()
 {
 }
 
 wxToolBar::~wxToolBar()
 {
+    // Make sure the toolbar is removed from the parent.
+    SetSize(0,0);
 }
 
 void wxToolBar::SetMargins(int x, int y)
 }
 
 void wxToolBar::SetMargins(int x, int y)
@@ -188,7 +235,7 @@ wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
             return NULL;
     }
 
             return NULL;
     }
 
-    for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
+    for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
           node;
           node = node->GetNext() )
     {
           node;
           node = node->GetNext() )
     {
@@ -213,7 +260,7 @@ void wxToolBar::SetToolShortHelp(int id, const wxString& help)
 {
     wxToolBarToolBase *tool = FindById(id);
 
 {
     wxToolBarToolBase *tool = FindById(id);
 
-    wxCHECK_RET( tool, _T("SetToolShortHelp: no such tool") );
+    wxCHECK_RET( tool, wxT("SetToolShortHelp: no such tool") );
 
     tool->SetShortHelp(help);
 }
 
     tool->SetShortHelp(help);
 }
@@ -222,80 +269,36 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos),
                              wxToolBarToolBase * WXUNUSED(tool))
 {
     // recalculate the toolbar geometry before redrawing it the next time
                              wxToolBarToolBase * WXUNUSED(tool))
 {
     // recalculate the toolbar geometry before redrawing it the next time
-    m_needsLayout = TRUE;
+    m_needsLayout = true;
 
     // and ensure that we indeed are going to redraw
     Refresh();
 
 
     // and ensure that we indeed are going to redraw
     Refresh();
 
-    return TRUE;
+    return true;
 }
 
 bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos),
                              wxToolBarToolBase * WXUNUSED(tool))
 {
     // as above
 }
 
 bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos),
                              wxToolBarToolBase * WXUNUSED(tool))
 {
     // as above
-    m_needsLayout = TRUE;
+    m_needsLayout = true;
 
     Refresh();
 
 
     Refresh();
 
-    return TRUE;
+    return true;
 }
 
 void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable)
 {
 }
 
 void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable)
 {
+#if wxUSE_IMAGE
     // created disabled-state bitmap on demand
     // created disabled-state bitmap on demand
-    if ( !enable && !tool->GetDisabledBitmap().Ok() )
+    if ( !enable && !tool->GetDisabledBitmap().IsOk() )
     {
     {
-        wxImage image( tool->GetNormalBitmap().ConvertToImage() );
-
-        // TODO: don't hardcode 180
-        unsigned char bg_red = 180;
-        unsigned char bg_green = 180;
-        unsigned char bg_blue = 180;
+        wxImage image(tool->GetNormalBitmap().ConvertToImage());
 
 
-        unsigned char mask_red = image.GetMaskRed();
-        unsigned char mask_green = image.GetMaskGreen();
-        unsigned char mask_blue = image.GetMaskBlue();
-
-        bool has_mask = image.HasMask();
-
-        int x,y;
-        for (y = 0; y < image.GetHeight(); y++)
-        {
-            for (x = 0; x < image.GetWidth(); x++)
-            {
-                unsigned char red = image.GetRed(x,y);
-                unsigned char green = image.GetGreen(x,y);
-                unsigned char blue = image.GetBlue(x,y);
-                if (!has_mask || red != mask_red || green != mask_green || blue != mask_blue)
-                {
-                    red = (((wxInt32) red  - bg_red) >> 1) + bg_red;
-                    green = (((wxInt32) green  - bg_green) >> 1) + bg_green;
-                    blue = (((wxInt32) blue  - bg_blue) >> 1) + bg_blue;
-                    image.SetRGB( x, y, red, green, blue );
-                }
-            }
-        }
-
-        for (y = 0; y < image.GetHeight(); y++)
-        {
-            for (x = y % 2; x < image.GetWidth(); x += 2)
-            {
-                unsigned char red = image.GetRed(x,y);
-                unsigned char green = image.GetGreen(x,y);
-                unsigned char blue = image.GetBlue(x,y);
-                if (!has_mask || red != mask_red || green != mask_green || blue != mask_blue)
-                {
-                    red = (((wxInt32) red  - bg_red) >> 1) + bg_red;
-                    green = (((wxInt32) green  - bg_green) >> 1) + bg_green;
-                    blue = (((wxInt32) blue  - bg_blue) >> 1) + bg_blue;
-                    image.SetRGB( x, y, red, green, blue );
-                }
-            }
-        }
-
-        tool->SetDisabledBitmap(image);
+        tool->SetDisabledBitmap(image.ConvertToGreyscale());
     }
     }
+#endif // wxUSE_IMAGE
 
     RefreshTool(tool);
 }
 
     RefreshTool(tool);
 }
@@ -325,11 +328,10 @@ wxToolBarToolBase *wxToolBar::CreateTool(int id,
                              clientData, shortHelp, longHelp);
 }
 
                              clientData, shortHelp, longHelp);
 }
 
-wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
+wxToolBarToolBase *
+wxToolBar::CreateTool(wxControl *control, const wxString& label)
 {
 {
-    wxFAIL_MSG( wxT("Toolbar doesn't support controls yet (TODO)") );
-
-    return NULL;
+    return new wxToolBarTool(this, control, label);
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -342,7 +344,7 @@ wxRect wxToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
 
     wxRect rect;
 
 
     wxRect rect;
 
-    wxCHECK_MSG( tool, rect, _T("GetToolRect: NULL tool") );
+    wxCHECK_MSG( tool, rect, wxT("GetToolRect: NULL tool") );
 
     // ensure that we always have the valid tool position
     if ( m_needsLayout )
 
     // ensure that we always have the valid tool position
     if ( m_needsLayout )
@@ -355,13 +357,57 @@ wxRect wxToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
 
     if ( IsVertical() )
     {
 
     if ( IsVertical() )
     {
-        rect.width = m_defaultWidth;
-        rect.height = tool->IsSeparator() ? m_widthSeparator : m_defaultHeight;
+        if (tool->IsButton())
+        {
+            if(!HasFlag(wxTB_TEXT))
+            {
+                rect.width = m_defaultWidth;
+                rect.height = m_defaultHeight;
+            }
+            else
+            {
+                rect.width = m_defaultWidth +
+                    GetFont().GetPointSize() * tool->GetLabel().length();
+                rect.height = m_defaultHeight;
+            }
+        }
+        else if (tool->IsSeparator())
+        {
+            rect.width = m_defaultWidth;
+            rect.height = m_widthSeparator;
+        }
+        else // control
+        {
+            rect.width = tool->m_width;
+            rect.height = tool->m_height;
+        }
     }
     else // horizontal
     {
     }
     else // horizontal
     {
-        rect.width = tool->IsSeparator() ? m_widthSeparator : m_defaultWidth;
-        rect.height = m_defaultHeight;
+        if (tool->IsButton())
+        {
+            if(!HasFlag(wxTB_TEXT))
+            {
+                rect.width = m_defaultWidth;
+                rect.height = m_defaultHeight;
+            }
+            else
+            {
+                rect.width = m_defaultWidth +
+                    GetFont().GetPointSize() * tool->GetLabel().length();
+                rect.height = m_defaultHeight;
+            }
+        }
+        else if (tool->IsSeparator())
+        {
+            rect.width = m_widthSeparator;
+            rect.height = m_defaultHeight;
+        }
+        else // control
+        {
+            rect.width = tool->m_width;
+            rect.height = tool->m_height;
+        }
     }
 
     rect.width += 2*m_xMargin;
     }
 
     rect.width += 2*m_xMargin;
@@ -373,31 +419,64 @@ wxRect wxToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
 bool wxToolBar::Realize()
 {
     if ( !wxToolBarBase::Realize() )
 bool wxToolBar::Realize()
 {
     if ( !wxToolBarBase::Realize() )
-        return FALSE;
+        return false;
 
 
-    m_needsLayout = TRUE;
+    m_needsLayout = true;
     DoLayout();
 
     DoLayout();
 
-    SetBestSize(wxDefaultSize);
+    // the first item in the radio group is checked by default to be consistent
+    // with wxGTK and the menu radio items
+    int radioGroupCount = 0;
 
 
-    return TRUE;
+    for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+          node;
+          node = node->GetNext() )
+    {
+        wxToolBarTool *tool = (wxToolBarTool*) node->GetData();
+
+        if ( !tool->IsButton() || tool->GetKind() != wxITEM_RADIO )
+        {
+            radioGroupCount = 0;
+            continue;
+        }
+
+        bool toggle = !radioGroupCount++;
+        if ( tool->Toggle(toggle) )
+        {
+            DoToggleTool(tool, toggle);
+        }
+    }
+
+    SetInitialSize(wxDefaultSize);
+
+    return true;
+}
+
+void wxToolBar::SetWindowStyleFlag( long style )
+{
+    wxToolBarBase::SetWindowStyleFlag(style);
+
+    m_needsLayout = true;
+
+    Refresh();
 }
 
 void wxToolBar::DoLayout()
 {
 }
 
 void wxToolBar::DoLayout()
 {
-    wxASSERT_MSG( m_needsLayout, _T("why are we called?") );
+    wxASSERT_MSG( m_needsLayout, wxT("why are we called?") );
 
 
-    m_needsLayout = FALSE;
+    m_needsLayout = false;
 
     wxCoord x = m_xMargin,
             y = m_yMargin;
 
 
     wxCoord x = m_xMargin,
             y = m_yMargin;
 
-    const wxCoord widthTool = IsVertical() ? m_defaultHeight : m_defaultWidth;
-    wxCoord margin = IsVertical() ? m_xMargin : m_yMargin,
-           *pCur = IsVertical() ? &y : &x;
+    wxCoord widthTool = 0, maxWidthTool = 0;
+    wxCoord heightTool = 0, maxHeightTool = 0;
+    wxCoord margin = IsVertical() ? m_xMargin : m_yMargin;
+    wxCoord *pCur = IsVertical() ? &y : &x;
 
     // calculate the positions of all elements
 
     // calculate the positions of all elements
-    for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
+    for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
           node;
           node = node->GetNext() )
     {
           node;
           node = node->GetNext() )
     {
@@ -407,12 +486,74 @@ void wxToolBar::DoLayout()
         tool->m_y = y;
 
         // TODO ugly number fiddling
         tool->m_y = y;
 
         // TODO ugly number fiddling
-        *pCur += ( tool->IsSeparator() ? m_widthSeparator : (widthTool+2) ) + margin;
+        if (tool->IsButton())
+        {
+            if (IsVertical())
+            {
+                widthTool = m_defaultHeight;
+                heightTool = m_defaultWidth;
+                if(HasFlag(wxTB_TEXT))
+                    heightTool += GetFont().GetPointSize() * tool->GetLabel().length();
+            }
+            else
+            {
+                widthTool = m_defaultWidth;
+                if(HasFlag(wxTB_TEXT))
+                    widthTool += GetFont().GetPointSize() * tool->GetLabel().length();
+
+                heightTool = m_defaultHeight;
+            }
+
+            if(widthTool > maxWidthTool) // Record max width of tool
+            {
+                maxWidthTool = widthTool;
+            }
+
+            if(heightTool > maxHeightTool) // Record max width of tool
+            {
+                maxHeightTool = heightTool;
+            }
+
+            *pCur += widthTool;
+        }
+        else if (tool->IsSeparator())
+        {
+            *pCur += m_widthSeparator;
+        }
+        else if (!IsVertical()) // horizontal control
+        {
+            wxControl *control = tool->GetControl();
+            wxSize size = control->GetSize();
+            tool->m_y += (m_defaultHeight - size.y)/2;
+            tool->m_width = size.x;
+            tool->m_height = size.y;
+
+            *pCur += tool->m_width;
+        }
+        *pCur += margin;
     }
 
     // calculate the total toolbar size
     }
 
     // calculate the total toolbar size
-    wxCoord xMin = m_defaultWidth + 2*m_xMargin,
-            yMin = m_defaultHeight + 2*m_yMargin;
+    wxCoord xMin, yMin;
+
+    if(!HasFlag(wxTB_TEXT))
+    {
+        xMin = m_defaultWidth + 2*m_xMargin;
+        yMin = m_defaultHeight + 2*m_yMargin;
+    }
+    else
+    {
+        if (IsVertical())
+        {
+            xMin = heightTool + 2*m_xMargin;
+            yMin = widthTool + 2*m_xMargin;
+        }
+        else
+        {
+            xMin = maxWidthTool + 2*m_xMargin;
+            yMin = heightTool + 2*m_xMargin;
+        }
+    }
 
     m_maxWidth = x < xMin ? xMin : x;
     m_maxHeight = y < yMin ? yMin : y;
 
     m_maxWidth = x < xMin ? xMin : x;
     m_maxHeight = y < yMin ? yMin : y;
@@ -423,6 +564,33 @@ wxSize wxToolBar::DoGetBestClientSize() const
     return wxSize(m_maxWidth, m_maxHeight);
 }
 
     return wxSize(m_maxWidth, m_maxHeight);
 }
 
+void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags)
+{
+    int old_width, old_height;
+    GetSize(&old_width, &old_height);
+
+    wxToolBarBase::DoSetSize(x, y, width, height, sizeFlags);
+
+    // Correct width and height if needed.
+    if ( width == wxDefaultCoord || height == wxDefaultCoord )
+    {
+        int tmp_width, tmp_height;
+        GetSize(&tmp_width, &tmp_height);
+
+        if ( width == wxDefaultCoord )
+            width = tmp_width;
+        if ( height == wxDefaultCoord )
+            height = tmp_height;
+    }
+
+    // We must refresh the frame size when the toolbar changes size
+    // otherwise the toolbar can be shown incorrectly
+    if ( old_width != width || old_height != height )
+    {
+        SendSizeEventToParent();
+    }
+}
+
 // ----------------------------------------------------------------------------
 // wxToolBar drawing
 // ----------------------------------------------------------------------------
 // ----------------------------------------------------------------------------
 // wxToolBar drawing
 // ----------------------------------------------------------------------------
@@ -436,7 +604,7 @@ void wxToolBar::GetRectLimits(const wxRect& rect,
                               wxCoord *start,
                               wxCoord *end) const
 {
                               wxCoord *start,
                               wxCoord *end) const
 {
-    wxCHECK_RET( start && end, _T("NULL pointer in GetRectLimits") );
+    wxCHECK_RET( start && end, wxT("NULL pointer in GetRectLimits") );
 
     if ( IsVertical() )
     {
 
     if ( IsVertical() )
     {
@@ -455,7 +623,7 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer)
     // prepare the variables used below
     wxDC& dc = renderer->GetDC();
     wxRenderer *rend = renderer->GetRenderer();
     // prepare the variables used below
     wxDC& dc = renderer->GetDC();
     wxRenderer *rend = renderer->GetRenderer();
-    // dc.SetFont(GetFont()); -- uncomment when we support labels
+    dc.SetFont(GetFont());
 
     // draw the border separating us from the menubar (if there is no menubar
     // we probably shouldn't draw it?)
 
     // draw the border separating us from the menubar (if there is no menubar
     // we probably shouldn't draw it?)
@@ -470,7 +638,7 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer)
     GetRectLimits(rectUpdate, &start, &end);
 
     // and redraw all the tools intersecting it
     GetRectLimits(rectUpdate, &start, &end);
 
     // and redraw all the tools intersecting it
-    for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
+    for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
           node;
           node = node->GetNext() )
     {
           node;
           node = node->GetNext() )
     {
@@ -490,13 +658,13 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer)
             // we're beyond the area to redraw, nothing left to do
             break;
         }
             // we're beyond the area to redraw, nothing left to do
             break;
         }
-        
+
         if (tool->IsSeparator() && !HasFlag(wxTB_FLAT))
         {
         if (tool->IsSeparator() && !HasFlag(wxTB_FLAT))
         {
-            // Draw seperators only in flat mode
+            // Draw separators only in flat mode
             continue;
         }
             continue;
         }
-        
+
         // deal with the flags
         int flags = 0;
 
         // deal with the flags
         int flags = 0;
 
@@ -521,12 +689,34 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer)
         wxBitmap bitmap;
         if ( !tool->IsSeparator() )
         {
         wxBitmap bitmap;
         if ( !tool->IsSeparator() )
         {
-            // label = tool->GetLabel();
+            label = tool->GetLabel();
             bitmap = tool->GetBitmap();
             bitmap = tool->GetBitmap();
+
+            if ( !bitmap.IsOk() )
+            {
+                // it's better not to draw anything than to assert inside
+                // drawing code as this results in an almost guaranteed crash
+                // as we're likely to be called by a paint event handler and so
+                // the assert is going to be triggered again and again and ...
+                continue;
+            }
         }
         //else: leave both the label and the bitmap invalid to draw a separator
 
         }
         //else: leave both the label and the bitmap invalid to draw a separator
 
-        rend->DrawToolBarButton(dc, label, bitmap, rectTool, flags);
+        if ( !tool->IsControl() )
+        {
+            int tbStyle = HasFlag(wxTB_VERTICAL) ? wxTB_VERTICAL : wxTB_HORIZONTAL;
+            if ( HasFlag(wxTB_TEXT) )
+                tbStyle |= wxTB_TEXT;
+
+            rend->DrawToolBarButton(dc, label, bitmap, rectTool, flags,
+                                    tool->GetStyle(), tbStyle);
+        }
+        else // control
+        {
+            wxControl *control = tool->GetControl();
+            control->Move(tool->m_x, tool->m_y);
+        }
     }
 }
 
     }
 }
 
@@ -539,28 +729,37 @@ bool wxToolBar::PerformAction(const wxControlAction& action,
                               const wxString& strArg)
 {
     wxToolBarTool *tool = (wxToolBarTool*) FindById(numArg);
                               const wxString& strArg)
 {
     wxToolBarTool *tool = (wxToolBarTool*) FindById(numArg);
-    
+    if (!tool)
+        return false;
+
     if ( action == wxACTION_TOOLBAR_TOGGLE )
     {
         PerformAction( wxACTION_BUTTON_RELEASE, numArg );
 
         PerformAction( wxACTION_BUTTON_CLICK, numArg );
     if ( action == wxACTION_TOOLBAR_TOGGLE )
     {
         PerformAction( wxACTION_BUTTON_RELEASE, numArg );
 
         PerformAction( wxACTION_BUTTON_CLICK, numArg );
+
+        // Set mouse leave toolbar button range (If still in the range,
+        // toolbar button would get focus again
+        PerformAction( wxACTION_TOOLBAR_LEAVE, numArg );
     }
     else if ( action == wxACTION_TOOLBAR_PRESS )
     {
     }
     else if ( action == wxACTION_TOOLBAR_PRESS )
     {
-        wxLogTrace(_T("toolbar"), _T("Button '%s' pressed."), tool->GetShortHelp().c_str());
-        
+        wxLogTrace(wxT("toolbar"), wxT("Button '%s' pressed."), tool->GetShortHelp().c_str());
+
         tool->Invert();
 
         RefreshTool( tool );
     }
     else if ( action == wxACTION_TOOLBAR_RELEASE )
     {
         tool->Invert();
 
         RefreshTool( tool );
     }
     else if ( action == wxACTION_TOOLBAR_RELEASE )
     {
-        wxLogTrace(_T("toolbar"), _T("Button '%s' released."), tool->GetShortHelp().c_str());
+        wxLogTrace(wxT("toolbar"), wxT("Button '%s' released."), tool->GetShortHelp().c_str());
 
 
-        wxASSERT_MSG( tool->IsInverted(), _T("release unpressed button?") );
-    
-        tool->Invert();
+        wxASSERT_MSG( tool->IsInverted(), wxT("release unpressed button?") );
+
+        if(tool->IsInverted())
+        {
+            tool->Invert();
+        }
 
         RefreshTool( tool );
     }
 
         RefreshTool( tool );
     }
@@ -569,7 +768,15 @@ bool wxToolBar::PerformAction(const wxControlAction& action,
         bool isToggled;
         if ( tool->CanBeToggled() )
         {
         bool isToggled;
         if ( tool->CanBeToggled() )
         {
-            tool->Toggle();
+            if ( tool->IsButton() && tool->GetKind() == wxITEM_RADIO )
+            {
+                UnToggleRadioGroup(tool);
+                tool->Toggle(true);
+            }
+            else
+            {
+                tool->Toggle();
+            }
 
             RefreshTool( tool );
 
 
             RefreshTool( tool );
 
@@ -577,30 +784,30 @@ bool wxToolBar::PerformAction(const wxControlAction& action,
         }
         else // simple non-checkable tool
         {
         }
         else // simple non-checkable tool
         {
-            isToggled = FALSE;
+            isToggled = false;
         }
         OnLeftClick( tool->GetId(), isToggled );
     }
     else if ( action == wxACTION_TOOLBAR_ENTER )
     {
         }
         OnLeftClick( tool->GetId(), isToggled );
     }
     else if ( action == wxACTION_TOOLBAR_ENTER )
     {
-        wxCHECK_MSG( tool, FALSE, _T("no tool to enter?") );
-        
+        wxCHECK_MSG( tool, false, wxT("no tool to enter?") );
+
         if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() )
         {
         if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() )
         {
-            tool->SetUnderMouse( TRUE );
-            
+            tool->SetUnderMouse( true );
+
             if ( !tool->IsToggled() )
                 RefreshTool( tool );
         }
     }
     else if ( action == wxACTION_TOOLBAR_LEAVE )
     {
             if ( !tool->IsToggled() )
                 RefreshTool( tool );
         }
     }
     else if ( action == wxACTION_TOOLBAR_LEAVE )
     {
-        wxCHECK_MSG( tool, FALSE, _T("no tool to leave?") );
-        
+        wxCHECK_MSG( tool, false, wxT("no tool to leave?") );
+
         if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() )
         {
         if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() )
         {
-            tool->SetUnderMouse( FALSE );
-            
+            tool->SetUnderMouse( false );
+
             if ( !tool->IsToggled() )
                 RefreshTool( tool );
         }
             if ( !tool->IsToggled() )
                 RefreshTool( tool );
         }
@@ -608,7 +815,15 @@ bool wxToolBar::PerformAction(const wxControlAction& action,
     else
         return wxControl::PerformAction(action, numArg, strArg);
 
     else
         return wxControl::PerformAction(action, numArg, strArg);
 
-    return TRUE;
+    return true;
+}
+
+/* static */
+wxInputHandler *wxToolBar::GetStdInputHandler(wxInputHandler *handlerDef)
+{
+    static wxStdToolbarInputHandler s_handler(handlerDef);
+
+    return &s_handler;
 }
 
 // ============================================================================
 }
 
 // ============================================================================
@@ -644,16 +859,16 @@ bool wxStdToolbarInputHandler::HandleMouse(wxInputConsumer *consumer,
         if ( event.LeftDown() || event.LeftDClick() )
         {
             if ( !tool || !tool->IsEnabled() )
         if ( event.LeftDown() || event.LeftDClick() )
         {
             if ( !tool || !tool->IsEnabled() )
-                return TRUE;
-                
+                return true;
+
             m_winCapture = tbar;
             m_winCapture->CaptureMouse();
             m_winCapture = tbar;
             m_winCapture->CaptureMouse();
-            
+
             m_toolCapture = tool;
 
             consumer->PerformAction( wxACTION_BUTTON_PRESS, tool->GetId() );
 
             m_toolCapture = tool;
 
             consumer->PerformAction( wxACTION_BUTTON_PRESS, tool->GetId() );
 
-            return TRUE;
+            return true;
         }
         else if ( event.LeftUp() )
         {
         }
         else if ( event.LeftUp() )
         {
@@ -670,10 +885,10 @@ bool wxStdToolbarInputHandler::HandleMouse(wxInputConsumer *consumer,
                 else
                     consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
             }
                 else
                     consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
             }
-            
+
             m_toolCapture = NULL;
             m_toolCapture = NULL;
-                
-            return TRUE;
+
+            return true;
         }
         //else: don't do anything special about the double click
     }
         }
         //else: don't do anything special about the double click
     }
@@ -687,7 +902,7 @@ bool wxStdToolbarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
     if ( !wxStdInputHandler::HandleMouseMove(consumer, event) )
     {
         wxToolBar *tbar = wxStaticCast(consumer->GetInputWindow(), wxToolBar);
     if ( !wxStdInputHandler::HandleMouseMove(consumer, event) )
     {
         wxToolBar *tbar = wxStaticCast(consumer->GetInputWindow(), wxToolBar);
-        
+
         wxToolBarTool *tool;
         if ( event.Leaving() )
         {
         wxToolBarTool *tool;
         if ( event.Leaving() )
         {
@@ -699,59 +914,59 @@ bool wxStdToolbarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
         {
             tool = (wxToolBarTool*) tbar->FindToolForPosition( event.GetX(), event.GetY() );
         }
         {
             tool = (wxToolBarTool*) tbar->FindToolForPosition( event.GetX(), event.GetY() );
         }
-        
+
         if (m_toolCapture)
         {
             // During capture we only care of the captured tool
             if (tool && (tool != m_toolCapture))
                 tool = NULL;
         if (m_toolCapture)
         {
             // During capture we only care of the captured tool
             if (tool && (tool != m_toolCapture))
                 tool = NULL;
-                
+
             if (tool == m_toolLast)
             if (tool == m_toolLast)
-                return TRUE;
-                
+                return true;
+
             if (tool)
                 consumer->PerformAction( wxACTION_BUTTON_PRESS, m_toolCapture->GetId() );
             else
                 consumer->PerformAction( wxACTION_BUTTON_RELEASE, m_toolCapture->GetId() );
             if (tool)
                 consumer->PerformAction( wxACTION_BUTTON_PRESS, m_toolCapture->GetId() );
             else
                 consumer->PerformAction( wxACTION_BUTTON_RELEASE, m_toolCapture->GetId() );
-                
+
             m_toolLast = tool;
         }
         else
         {
             if (tool == m_toolLast)
             m_toolLast = tool;
         }
         else
         {
             if (tool == m_toolLast)
-               return TRUE;
-               
+               return true;
+
             if (m_toolLast)
             {
                 // Leave old tool if any
                 consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolLast->GetId() );
             }
             if (m_toolLast)
             {
                 // Leave old tool if any
                 consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolLast->GetId() );
             }
-            
+
             if (tool)
             {
                 // Enter new tool if any
                 consumer->PerformAction( wxACTION_TOOLBAR_ENTER, tool->GetId() );
             }
             if (tool)
             {
                 // Enter new tool if any
                 consumer->PerformAction( wxACTION_TOOLBAR_ENTER, tool->GetId() );
             }
-        
+
             m_toolLast = tool;
         }
             m_toolLast = tool;
         }
-        
-        return TRUE;
+
+        return true;
     }
 
     }
 
-    return FALSE;
+    return false;
 }
 
 bool wxStdToolbarInputHandler::HandleFocus(wxInputConsumer *consumer,
 }
 
 bool wxStdToolbarInputHandler::HandleFocus(wxInputConsumer *consumer,
-                                           const wxFocusEvent& event)
+                                           const wxFocusEvent& WXUNUSED(event))
 {
 {
-    if (m_toolCapture)
+    if ( m_toolCapture )
     {
         // We shouldn't be left with a highlighted button
         consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
     }
 
     {
         // We shouldn't be left with a highlighted button
         consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
     }
 
-    return TRUE;
+    return true;
 }
 
 bool wxStdToolbarInputHandler::HandleActivation(wxInputConsumer *consumer,
 }
 
 bool wxStdToolbarInputHandler::HandleActivation(wxInputConsumer *consumer,
@@ -763,8 +978,7 @@ bool wxStdToolbarInputHandler::HandleActivation(wxInputConsumer *consumer,
         consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
     }
 
         consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
     }
 
-    return TRUE;
+    return true;
 }
 
 #endif // wxUSE_TOOLBAR
 }
 
 #endif // wxUSE_TOOLBAR
-