]> git.saurik.com Git - wxWidgets.git/blobdiff - src/univ/toolbar.cpp
Workaround for special menu items not always being enabled. Use
[wxWidgets.git] / src / univ / toolbar.cpp
index 378931a6b5aa9a7daccf641066e93a5b4124a42b..09ef2621672ef49024e7aa12b4d02572e0ae4449 100644 (file)
@@ -18,7 +18,7 @@
 // headers
 // ----------------------------------------------------------------------------
 
-#ifdef __GNUG__
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
     #pragma implementation "univtoolbar.h"
 #endif
 
 
 #include "wx/univ/renderer.h"
 
+#include "wx/frame.h"
 #include "wx/toolbar.h"
 #include "wx/image.h"
+#include "wx/log.h"
 
 // ----------------------------------------------------------------------------
 // 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
@@ -69,13 +71,31 @@ public:
     {
         // no position yet
         m_x =
-        m_y = -1;
+        m_y = wxDefaultCoord;
+        m_width =
+        m_height = 0;
 
         // not pressed yet
-        m_isInverted = FALSE;
+        m_isInverted = false;
         
         // mouse not here yet
-        m_underMouse = FALSE;
+        m_underMouse = false;
+    }
+
+    wxToolBarTool(wxToolBar *tbar, wxControl *control)
+        : wxToolBarToolBase(tbar, control)
+    {
+        // 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
@@ -90,19 +110,21 @@ public:
     void Invert() { m_isInverted = !m_isInverted; }
     
     // Set underMouse
-    void SetUnderMouse( bool under = TRUE ) { m_underMouse = under; }
+    void SetUnderMouse( bool under = true ) { m_underMouse = under; }
     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:
-    // TRUE if the tool is pressed
+    // true if the tool is pressed
     bool m_isInverted;
     
-    // TRUE if the tool is under the mouse
+    // true if the tool is under the mouse
     bool m_underMouse;
 };
 
@@ -119,7 +141,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl);
 void wxToolBar::Init()
 {
     // no tools yet
-    m_needsLayout = FALSE;
+    m_needsLayout = false;
 
     // unknown widths for the tools and separators
     m_widthSeparator = INVALID_WIDTH;
@@ -143,18 +165,20 @@ bool wxToolBar::Create(wxWindow *parent,
     if ( !wxToolBarBase::Create(parent, id, pos, size, style,
                                 wxDefaultValidator, name) )
     {
-        return FALSE;
+        return false;
     }
 
     CreateInputHandler(wxINP_HANDLER_TOOLBAR);
 
     SetBestSize(size);
 
-    return TRUE;
+    return true;
 }
 
 wxToolBar::~wxToolBar()
 {
+    // Make sure the toolbar is removed from the parent.
+    SetSize(0,0);
 }
 
 void wxToolBar::SetMargins(int x, int y)
@@ -187,7 +211,7 @@ wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
             return NULL;
     }
 
-    for ( wxToolBarToolsList::Node *node = m_tools.GetFirst();
+    for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
           node;
           node = node->GetNext() )
     {
@@ -221,23 +245,23 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos),
                              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();
 
-    return TRUE;
+    return true;
 }
 
 bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos),
                              wxToolBarToolBase * WXUNUSED(tool))
 {
     // as above
-    m_needsLayout = TRUE;
+    m_needsLayout = true;
 
     Refresh();
 
-    return TRUE;
+    return true;
 }
 
 void wxToolBar::DoEnableTool(wxToolBarToolBase *tool, bool enable)
@@ -326,9 +350,7 @@ wxToolBarToolBase *wxToolBar::CreateTool(int id,
 
 wxToolBarToolBase *wxToolBar::CreateTool(wxControl *control)
 {
-    wxFAIL_MSG( wxT("Toolbar doesn't support controls yet (TODO)") );
-
-    return NULL;
+    return new wxToolBarTool(this, control);
 }
 
 // ----------------------------------------------------------------------------
@@ -354,13 +376,39 @@ wxRect wxToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
 
     if ( IsVertical() )
     {
-        rect.width = m_defaultWidth;
-        rect.height = tool->IsSeparator() ? m_widthSeparator : m_defaultHeight;
+        if (tool->IsButton())
+        {
+            rect.width = m_defaultWidth;
+            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
     {
-        rect.width = tool->IsSeparator() ? m_widthSeparator : m_defaultWidth;
-        rect.height = m_defaultHeight;
+        if (tool->IsButton())
+        {
+            rect.width = m_defaultWidth;
+            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;
@@ -372,21 +420,21 @@ wxRect wxToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
 bool wxToolBar::Realize()
 {
     if ( !wxToolBarBase::Realize() )
-        return FALSE;
+        return false;
 
-    m_needsLayout = TRUE;
+    m_needsLayout = true;
     DoLayout();
 
     SetBestSize(wxDefaultSize);
 
-    return TRUE;
+    return true;
 }
 
 void wxToolBar::DoLayout()
 {
     wxASSERT_MSG( m_needsLayout, _T("why are we called?") );
 
-    m_needsLayout = FALSE;
+    m_needsLayout = false;
 
     wxCoord x = m_xMargin,
             y = m_yMargin;
@@ -396,7 +444,7 @@ void wxToolBar::DoLayout()
            *pCur = IsVertical() ? &y : &x;
 
     // 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() )
     {
@@ -406,7 +454,25 @@ void wxToolBar::DoLayout()
         tool->m_y = y;
 
         // TODO ugly number fiddling
-        *pCur += ( tool->IsSeparator() ? m_widthSeparator : (widthTool+2) ) + margin;
+        if (tool->IsButton())
+        {
+            *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
@@ -422,6 +488,39 @@ wxSize wxToolBar::DoGetBestClientSize() const
     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 )
+    {
+        // But before we send the size event check it 
+        // we have a frame that is not being deleted.
+        wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
+        if ( frame && !frame->IsBeingDeleted() )
+        {
+            frame->SendSizeEvent();
+        }
+    }
+}
+
 // ----------------------------------------------------------------------------
 // wxToolBar drawing
 // ----------------------------------------------------------------------------
@@ -469,7 +568,7 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer)
     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() )
     {
@@ -525,7 +624,15 @@ void wxToolBar::DoDraw(wxControlRenderer *renderer)
         }
         //else: leave both the label and the bitmap invalid to draw a separator
 
-        rend->DrawToolBarButton(dc, label, bitmap, rectTool, flags);
+        if ( !tool->IsControl() )
+        {
+            rend->DrawToolBarButton(dc, label, bitmap, rectTool, flags, tool->GetStyle());
+        }
+        else // control
+        {
+            wxControl *control = tool->GetControl();
+            control->Move(tool->m_x, tool->m_y);
+        }
     }
 }
 
@@ -538,6 +645,8 @@ bool wxToolBar::PerformAction(const wxControlAction& action,
                               const wxString& strArg)
 {
     wxToolBarTool *tool = (wxToolBarTool*) FindById(numArg);
+    if (!tool)
+        return false;
     
     if ( action == wxACTION_TOOLBAR_TOGGLE )
     {
@@ -576,17 +685,17 @@ bool wxToolBar::PerformAction(const wxControlAction& action,
         }
         else // simple non-checkable tool
         {
-            isToggled = FALSE;
+            isToggled = false;
         }
         OnLeftClick( tool->GetId(), isToggled );
     }
     else if ( action == wxACTION_TOOLBAR_ENTER )
     {
-        wxCHECK_MSG( tool, FALSE, _T("no tool to enter?") );
+        wxCHECK_MSG( tool, false, _T("no tool to enter?") );
         
         if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() )
         {
-            tool->SetUnderMouse( TRUE );
+            tool->SetUnderMouse( true );
             
             if ( !tool->IsToggled() )
                 RefreshTool( tool );
@@ -594,11 +703,11 @@ bool wxToolBar::PerformAction(const wxControlAction& action,
     }
     else if ( action == wxACTION_TOOLBAR_LEAVE )
     {
-        wxCHECK_MSG( tool, FALSE, _T("no tool to leave?") );
+        wxCHECK_MSG( tool, false, _T("no tool to leave?") );
         
         if ( HasFlag(wxTB_FLAT) && tool->IsEnabled() )
         {
-            tool->SetUnderMouse( FALSE );
+            tool->SetUnderMouse( false );
             
             if ( !tool->IsToggled() )
                 RefreshTool( tool );
@@ -607,7 +716,7 @@ bool wxToolBar::PerformAction(const wxControlAction& action,
     else
         return wxControl::PerformAction(action, numArg, strArg);
 
-    return TRUE;
+    return true;
 }
 
 // ============================================================================
@@ -643,7 +752,7 @@ bool wxStdToolbarInputHandler::HandleMouse(wxInputConsumer *consumer,
         if ( event.LeftDown() || event.LeftDClick() )
         {
             if ( !tool || !tool->IsEnabled() )
-                return TRUE;
+                return true;
                 
             m_winCapture = tbar;
             m_winCapture->CaptureMouse();
@@ -652,7 +761,7 @@ bool wxStdToolbarInputHandler::HandleMouse(wxInputConsumer *consumer,
 
             consumer->PerformAction( wxACTION_BUTTON_PRESS, tool->GetId() );
 
-            return TRUE;
+            return true;
         }
         else if ( event.LeftUp() )
         {
@@ -662,14 +771,17 @@ bool wxStdToolbarInputHandler::HandleMouse(wxInputConsumer *consumer,
                 m_winCapture = NULL;
             }
 
-            if ( tool == m_toolCapture )
-                consumer->PerformAction( wxACTION_BUTTON_TOGGLE, m_toolCapture->GetId() );
-            else
-                consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
+            if (m_toolCapture)
+            {
+                if ( tool == m_toolCapture )
+                    consumer->PerformAction( wxACTION_BUTTON_TOGGLE, m_toolCapture->GetId() );
+                else
+                    consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
+            }
             
             m_toolCapture = NULL;
                 
-            return TRUE;
+            return true;
         }
         //else: don't do anything special about the double click
     }
@@ -703,7 +815,7 @@ bool wxStdToolbarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
                 tool = NULL;
                 
             if (tool == m_toolLast)
-                return TRUE;
+                return true;
                 
             if (tool)
                 consumer->PerformAction( wxACTION_BUTTON_PRESS, m_toolCapture->GetId() );
@@ -715,7 +827,7 @@ bool wxStdToolbarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
         else
         {
             if (tool == m_toolLast)
-               return TRUE;
+               return true;
                
             if (m_toolLast)
             {
@@ -732,22 +844,22 @@ bool wxStdToolbarInputHandler::HandleMouseMove(wxInputConsumer *consumer,
             m_toolLast = tool;
         }
         
-        return TRUE;
+        return true;
     }
 
-    return FALSE;
+    return false;
 }
 
 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() );
     }
 
-    return TRUE;
+    return true;
 }
 
 bool wxStdToolbarInputHandler::HandleActivation(wxInputConsumer *consumer,
@@ -759,7 +871,7 @@ bool wxStdToolbarInputHandler::HandleActivation(wxInputConsumer *consumer,
         consumer->PerformAction( wxACTION_TOOLBAR_LEAVE, m_toolCapture->GetId() );
     }
 
-    return TRUE;
+    return true;
 }
 
 #endif // wxUSE_TOOLBAR