]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/buttonbar.cpp
Ensure there is valid context for DrawRectangle
[wxWidgets.git] / src / generic / buttonbar.cpp
index 47308b318940b274144cb7103333085fc8a49801..82d43dc554806963208821fee3c18c58799c2b02 100644 (file)
@@ -6,7 +6,7 @@
 // Created:     2006-04-13
 // Id:          $Id$
 // Copyright:   (c) Julian Smart, Robert Roebling, Vadim Zeitlin,
-//              SciTech Software, Inc. 
+//              SciTech Software, Inc.
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 // Currently, only for Mac as a toolbar replacement.
 #if defined(__WXMAC__) && wxUSE_TOOLBAR && wxUSE_BMPBUTTON
 
+#include "wx/generic/buttonbar.h"
+
 #ifndef WX_PRECOMP
     #include "wx/utils.h"
     #include "wx/app.h"
+    #include "wx/log.h"
+    #include "wx/frame.h"
+    #include "wx/dcclient.h"
+    #include "wx/settings.h"
+    #include "wx/image.h"
 #endif
 
-#include "wx/generic/buttonbar.h"
-#include "wx/frame.h"
-#include "wx/image.h"
-#include "wx/log.h"
-
 // ----------------------------------------------------------------------------
 // wxButtonToolBarTool: our implementation of wxToolBarToolBase
 // ----------------------------------------------------------------------------
@@ -60,12 +62,14 @@ public:
         m_x = m_y = wxDefaultCoord;
         m_width =
         m_height = 0;
-        
+
         m_button = NULL;
     }
 
-    wxButtonToolBarTool(wxButtonToolBar *tbar, wxControl *control)
-        : wxToolBarToolBase(tbar, control)
+    wxButtonToolBarTool(wxButtonToolBar *tbar,
+                        wxControl *control,
+                        const wxString& label)
+        : wxToolBarToolBase(tbar, control, label)
     {
         m_x = m_y = wxDefaultCoord;
         m_width =
@@ -96,6 +100,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxButtonToolBar, wxControl)
 
 BEGIN_EVENT_TABLE(wxButtonToolBar, wxControl)
     EVT_BUTTON(wxID_ANY, wxButtonToolBar::OnCommand)
+    EVT_PAINT(wxButtonToolBar::OnPaint)
+    EVT_LEFT_UP(wxButtonToolBar::OnLeftUp)
 END_EVENT_TABLE()
 
 // ----------------------------------------------------------------------------
@@ -110,8 +116,13 @@ void wxButtonToolBar::Init()
     // unknown widths for the tools and separators
     m_widthSeparator = wxDefaultCoord;
 
-    m_maxWidth =
-    m_maxHeight = 0;
+    m_maxWidth = m_maxHeight = 0;
+
+    m_labelMargin = 2;
+    m_labelHeight = 0;
+
+    SetMargins(8, 2);
+    SetToolPacking(8);
 }
 
 bool wxButtonToolBar::Create(wxWindow *parent,
@@ -127,6 +138,23 @@ bool wxButtonToolBar::Create(wxWindow *parent,
         return false;
     }
 
+    // wxColour lightBackground(244, 244, 244);
+
+    wxFont font(wxSMALL_FONT->GetPointSize(),
+                wxNORMAL_FONT->GetFamily(),
+                wxNORMAL_FONT->GetStyle(),
+                wxFONTWEIGHT_NORMAL);
+    SetFont(font);
+
+    // Calculate the label height if necessary
+    if (GetWindowStyle() & wxTB_TEXT)
+    {
+        wxClientDC dc(this);
+        dc.SetFont(font);
+        int w, h;
+        dc.GetTextExtent(wxT("X"), & w, & h);
+        m_labelHeight = h;
+    }
     return true;
 }
 
@@ -182,7 +210,7 @@ void wxButtonToolBar::GetRectLimits(const wxRect& rect,
                               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() )
     {
@@ -201,7 +229,7 @@ void wxButtonToolBar::SetToolShortHelp(int id, const wxString& help)
 {
     wxToolBarToolBase *tool = FindById(id);
 
-    wxCHECK_RET( tool, _T("SetToolShortHelp: no such tool") );
+    wxCHECK_RET( tool, wxT("SetToolShortHelp: no such tool") );
 
     // TODO: set tooltip/short help
     tool->SetShortHelp(help);
@@ -248,9 +276,10 @@ wxToolBarToolBase *wxButtonToolBar::CreateTool(int id,
                              clientData, shortHelp, longHelp);
 }
 
-wxToolBarToolBase *wxButtonToolBar::CreateTool(wxControl *control)
+wxToolBarToolBase *wxButtonToolBar::CreateTool(wxControl *control,
+                                               const wxString& label)
 {
-    return new wxButtonToolBarTool(this, control);
+    return new wxButtonToolBarTool(this, control, label);
 }
 
 // ----------------------------------------------------------------------------
@@ -263,7 +292,7 @@ wxRect wxButtonToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
 
     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 )
@@ -271,8 +300,8 @@ wxRect wxButtonToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
         wxConstCast(this, wxButtonToolBar)->DoLayout();
     }
 
-    rect.x = tool->m_x - m_xMargin;
-    rect.y = tool->m_y - m_yMargin;
+    rect.x = tool->m_x - (m_toolPacking/2);
+    rect.y = tool->m_y;
 
     if ( IsVertical() )
     {
@@ -281,7 +310,7 @@ wxRect wxButtonToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
             rect.width = m_defaultWidth;
             rect.height = m_defaultHeight;
             if (tool->GetButton())
-                rect.SetSize(tool->GetButton()->GetSize());
+                rect.SetSize(wxSize(tool->m_width, tool->m_height));
         }
         else if (tool->IsSeparator())
         {
@@ -301,7 +330,7 @@ wxRect wxButtonToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
             rect.width = m_defaultWidth;
             rect.height = m_defaultHeight;
             if (tool->GetButton())
-                rect.SetSize(tool->GetButton()->GetSize());
+                rect.SetSize(wxSize(tool->m_width, tool->m_height));
         }
         else if (tool->IsSeparator())
         {
@@ -315,8 +344,7 @@ wxRect wxButtonToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
         }
     }
 
-    rect.width += 2*m_xMargin;
-    rect.height += 2*m_yMargin;
+    rect.width += m_toolPacking;
 
     return rect;
 }
@@ -325,11 +353,11 @@ bool wxButtonToolBar::Realize()
 {
     if ( !wxToolBarBase::Realize() )
         return false;
-    
+
     m_needsLayout = true;
     DoLayout();
-    
-    SetBestSize(wxSize(m_maxWidth, m_maxHeight));
+
+    SetInitialSize(wxSize(m_maxWidth, m_maxHeight));
 
     return true;
 }
@@ -356,28 +384,57 @@ void wxButtonToolBar::DoLayout()
 
         tool->m_x = x;
         tool->m_y = y;
-        
+
         if (tool->IsButton())
         {
             if (!tool->GetButton())
             {
                 wxBitmapButton* bmpButton = new wxBitmapButton(this, tool->GetId(), tool->GetNormalBitmap(), wxPoint(tool->m_x, tool->m_y), wxDefaultSize,
-                    wxBU_AUTODRAW);
-                
+                                                               wxBU_AUTODRAW|wxBORDER_NONE);
+                if (!tool->GetShortHelp().empty())
+                    bmpButton->SetLabel(tool->GetShortHelp());
+
                 tool->SetButton(bmpButton);
             }
             else
             {
                 tool->GetButton()->Move(wxPoint(tool->m_x, tool->m_y));
             }
-            
+
             int w = widthTool;
             if (tool->GetButton())
             {
                 wxSize sz = tool->GetButton()->GetSize();
                 w = sz.x;
 
+                if (m_labelHeight > 0)
+                {
+                    sz.y += (m_labelHeight + m_labelMargin);
+
+                    if (!tool->GetShortHelp().empty())
+                    {
+                        wxClientDC dc(this);
+                        dc.SetFont(GetFont());
+                        int tw, th;
+                        dc.GetTextExtent(tool->GetShortHelp(), & tw, & th);
+
+                        // If the label is bigger than the icon, the label width
+                        // becomes the new tool width, and we need to centre the
+                        // the bitmap in this box.
+                        if (tw > sz.x)
+                        {
+                            int newX = int(tool->m_x + (tw - sz.x)/2.0);
+                            tool->GetButton()->Move(newX, tool->m_y);
+                            sz.x = tw;
+                        }
+                    }
+                }
+
                 maxHeight = wxMax(maxHeight, sz.y);
+
+                tool->m_width = sz.x;
+                tool->m_height = sz.y;
+                w = sz.x;
             }
 
             *pCur += (w + GetToolPacking());
@@ -404,6 +461,10 @@ void wxButtonToolBar::DoLayout()
     // calculate the total toolbar size
     m_maxWidth = x + 2*m_xMargin;
     m_maxHeight = maxHeight + 2*m_yMargin;
+
+    if ((GetWindowStyle() & wxTB_NODIVIDER) == 0)
+        m_maxHeight += 2;
+
 }
 
 wxSize wxButtonToolBar::DoGetBestClientSize() const
@@ -421,9 +482,80 @@ void wxButtonToolBar::OnCommand(wxCommandEvent& event)
         return;
     }
 
+    if (tool->CanBeToggled())
+        tool->Toggle(tool->IsToggled());
+
     // TODO: handle toggle items
-    OnLeftClick(event.GetId(), false);    
+    OnLeftClick(event.GetId(), false);
+
+    if (tool->GetKind() == wxITEM_RADIO)
+        UnToggleRadioGroup(tool);
+
+    if (tool->CanBeToggled())
+        Refresh();
 }
 
-#endif // wxUSE_TOOLBAR && wxUSE_BMPBUTTON
+// paints a border
+void wxButtonToolBar::OnPaint(wxPaintEvent& WXUNUSED(event))
+{
+    wxPaintDC dc(this);
 
+    dc.SetFont(GetFont());
+    dc.SetBackgroundMode(wxTRANSPARENT);
+
+    for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+          node;
+          node = node->GetNext() )
+    {
+        wxButtonToolBarTool *tool =  (wxButtonToolBarTool*) node->GetData();
+        wxRect rectTool = GetToolRect(tool);
+        if (tool->IsToggled())
+        {
+            wxRect backgroundRect = rectTool;
+            backgroundRect.y = -1; backgroundRect.height = GetClientSize().y + 1;
+            wxBrush brush(wxColour(219, 219, 219));
+            wxPen pen(wxColour(159, 159, 159));
+            dc.SetBrush(brush);
+            dc.SetPen(pen);
+            dc.DrawRectangle(backgroundRect);
+        }
+
+        if (m_labelHeight > 0 && !tool->GetShortHelp().empty())
+        {
+            int tw, th;
+            dc.GetTextExtent(tool->GetShortHelp(), & tw, & th);
+
+            int x = tool->m_x;
+            dc.DrawText(tool->GetShortHelp(), x, tool->m_y + tool->GetButton()->GetSize().y + m_labelMargin);
+        }
+    }
+
+    if ((GetWindowStyle() & wxTB_NODIVIDER) == 0)
+    {
+        wxPen pen(wxColour(159, 159, 159));
+        dc.SetPen(pen);
+        int x1 = 0;
+        int y1 = GetClientSize().y-1;
+        int x2 = GetClientSize().x;
+        int y2 = y1;
+        dc.DrawLine(x1, y1, x2, y2);
+    }
+}
+
+// detects mouse clicks outside buttons
+void wxButtonToolBar::OnLeftUp(wxMouseEvent& event)
+{
+    if (m_labelHeight > 0)
+    {
+        wxButtonToolBarTool* tool = (wxButtonToolBarTool*) FindToolForPosition(event.GetX(), event.GetY());
+        if (tool && tool->GetButton() && (event.GetY() > (tool->m_y + tool->GetButton()->GetSize().y)))
+        {
+            wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, tool->GetId());
+            event.SetEventObject(tool->GetButton());
+            if (!GetEventHandler()->ProcessEvent(event))
+                event.Skip();
+        }
+    }
+}
+
+#endif // wxUSE_TOOLBAR && wxUSE_BMPBUTTON