+/////////////////////////////////////////////////////////////////////////////
+// Name: src/generic/buttonbar.cpp
+// Purpose: wxButtonToolBar implementation
+// Author: Julian Smart, after Robert Roebling, Vadim Zeitlin, SciTech
+// Modified by:
+// Created: 2006-04-13
+// Id: $Id$
+// Copyright: (c) Julian Smart, Robert Roebling, Vadim Zeitlin,
+// SciTech Software, Inc.
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#if wxUSE_TOOLBAR && wxUSE_BMPBUTTON
+
+#ifndef WX_PRECOMP
+ #include "wx/utils.h"
+ #include "wx/app.h"
+#endif
+
+#include "wx/generic/buttonbar.h"
+#include "wx/frame.h"
+#include "wx/image.h"
+#include "wx/log.h"
+
+// ----------------------------------------------------------------------------
+// wxButtonToolBarTool: our implementation of wxToolBarToolBase
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxButtonToolBarTool : public wxToolBarToolBase
+{
+public:
+ wxButtonToolBarTool(wxButtonToolBar *tbar,
+ int id,
+ const wxString& label,
+ const wxBitmap& bmpNormal,
+ const wxBitmap& bmpDisabled,
+ wxItemKind kind,
+ wxObject *clientData,
+ const wxString& shortHelp,
+ const wxString& longHelp)
+ : wxToolBarToolBase(tbar, id, label, bmpNormal, bmpDisabled, kind,
+ clientData, shortHelp, longHelp)
+ {
+ m_x = m_y = wxDefaultCoord;
+ m_width =
+ m_height = 0;
+
+ m_button = NULL;
+ }
+
+ wxButtonToolBarTool(wxButtonToolBar *tbar, wxControl *control)
+ : wxToolBarToolBase(tbar, control)
+ {
+ m_x = m_y = wxDefaultCoord;
+ m_width =
+ m_height = 0;
+ m_button = NULL;
+ }
+
+ wxBitmapButton* GetButton() const { return m_button; }
+ void SetButton(wxBitmapButton* button) { m_button = button; }
+
+public:
+ // the tool position (for controls)
+ wxCoord m_x;
+ wxCoord m_y;
+ wxCoord m_width;
+ wxCoord m_height;
+
+private:
+ // the control representing the button
+ wxBitmapButton* m_button;
+};
+
+// ============================================================================
+// wxButtonToolBar implementation
+// ============================================================================
+
+IMPLEMENT_DYNAMIC_CLASS(wxButtonToolBar, wxControl)
+
+BEGIN_EVENT_TABLE(wxButtonToolBar, wxControl)
+ EVT_BUTTON(wxID_ANY, wxButtonToolBar::OnCommand)
+END_EVENT_TABLE()
+
+// ----------------------------------------------------------------------------
+// wxButtonToolBar creation
+// ----------------------------------------------------------------------------
+
+void wxButtonToolBar::Init()
+{
+ // no tools yet
+ m_needsLayout = false;
+
+ // unknown widths for the tools and separators
+ m_widthSeparator = wxDefaultCoord;
+
+ m_maxWidth =
+ m_maxHeight = 0;
+}
+
+bool wxButtonToolBar::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
+{
+ if ( !wxToolBarBase::Create(parent, id, pos, size, style,
+ wxDefaultValidator, name) )
+ {
+ return false;
+ }
+
+ return true;
+}
+
+wxButtonToolBar::~wxButtonToolBar()
+{
+}
+
+// ----------------------------------------------------------------------------
+// wxButtonToolBar tool-related methods
+// ----------------------------------------------------------------------------
+
+wxToolBarToolBase *wxButtonToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
+{
+ // check the "other" direction first: it must be inside the toolbar or we
+ // don't risk finding anything
+ if ( IsVertical() )
+ {
+ if ( x < 0 || x > m_maxWidth )
+ return NULL;
+
+ // we always use x, even for a vertical toolbar, this makes the code
+ // below simpler
+ x = y;
+ }
+ else // horizontal
+ {
+ if ( y < 0 || y > m_maxHeight )
+ return NULL;
+ }
+
+ for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+ node;
+ node = node->GetNext() )
+ {
+ wxButtonToolBarTool *tool = (wxButtonToolBarTool*) node->GetData();
+ wxRect rectTool = GetToolRect(tool);
+
+ wxCoord startTool, endTool;
+ GetRectLimits(rectTool, &startTool, &endTool);
+
+ if ( x >= startTool && x <= endTool )
+ {
+ // don't return the separators from here, they don't accept any
+ // input anyhow
+ return tool->IsSeparator() ? NULL : tool;
+ }
+ }
+
+ return NULL;
+}
+
+void wxButtonToolBar::GetRectLimits(const wxRect& rect,
+ wxCoord *start,
+ wxCoord *end) const
+{
+ wxCHECK_RET( start && end, _T("NULL pointer in GetRectLimits") );
+
+ if ( IsVertical() )
+ {
+ *start = rect.GetTop();
+ *end = rect.GetBottom();
+ }
+ else // horizontal
+ {
+ *start = rect.GetLeft();
+ *end = rect.GetRight();
+ }
+}
+
+
+void wxButtonToolBar::SetToolShortHelp(int id, const wxString& help)
+{
+ wxToolBarToolBase *tool = FindById(id);
+
+ wxCHECK_RET( tool, _T("SetToolShortHelp: no such tool") );
+
+ // TODO: set tooltip/short help
+ tool->SetShortHelp(help);
+}
+
+bool wxButtonToolBar::DoInsertTool(size_t WXUNUSED(pos),
+ wxToolBarToolBase * WXUNUSED(tool))
+{
+ return true;
+}
+
+bool wxButtonToolBar::DoDeleteTool(size_t WXUNUSED(pos),
+ wxToolBarToolBase * WXUNUSED(tool))
+{
+ // TODO
+ return true;
+}
+
+void wxButtonToolBar::DoEnableTool(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(enable))
+{
+ // TODO
+}
+
+void wxButtonToolBar::DoToggleTool(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
+{
+ // TODO
+}
+
+void wxButtonToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
+{
+ // TODO
+}
+
+wxToolBarToolBase *wxButtonToolBar::CreateTool(int id,
+ const wxString& label,
+ const wxBitmap& bmpNormal,
+ const wxBitmap& bmpDisabled,
+ wxItemKind kind,
+ wxObject *clientData,
+ const wxString& shortHelp,
+ const wxString& longHelp)
+{
+ return new wxButtonToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
+ clientData, shortHelp, longHelp);
+}
+
+wxToolBarToolBase *wxButtonToolBar::CreateTool(wxControl *control)
+{
+ return new wxButtonToolBarTool(this, control);
+}
+
+// ----------------------------------------------------------------------------
+// wxButtonToolBar geometry
+// ----------------------------------------------------------------------------
+
+wxRect wxButtonToolBar::GetToolRect(wxToolBarToolBase *toolBase) const
+{
+ const wxButtonToolBarTool *tool = (wxButtonToolBarTool *)toolBase;
+
+ wxRect rect;
+
+ wxCHECK_MSG( tool, rect, _T("GetToolRect: NULL tool") );
+
+ // ensure that we always have the valid tool position
+ if ( m_needsLayout )
+ {
+ wxConstCast(this, wxButtonToolBar)->DoLayout();
+ }
+
+ rect.x = tool->m_x - m_xMargin;
+ rect.y = tool->m_y - m_yMargin;
+
+ if ( IsVertical() )
+ {
+ if (tool->IsButton())
+ {
+ rect.width = m_defaultWidth;
+ rect.height = m_defaultHeight;
+ if (tool->GetButton())
+ rect.SetSize(tool->GetButton()->GetSize());
+ }
+ 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
+ {
+ if (tool->IsButton())
+ {
+ rect.width = m_defaultWidth;
+ rect.height = m_defaultHeight;
+ if (tool->GetButton())
+ rect.SetSize(tool->GetButton()->GetSize());
+ }
+ 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.height += 2*m_yMargin;
+
+ return rect;
+}
+
+bool wxButtonToolBar::Realize()
+{
+ if ( !wxToolBarBase::Realize() )
+ return false;
+
+ m_needsLayout = true;
+ DoLayout();
+
+ SetBestSize(wxSize(m_maxWidth, m_maxHeight));
+
+ return true;
+}
+
+void wxButtonToolBar::DoLayout()
+{
+ m_needsLayout = false;
+
+ wxCoord x = m_xMargin,
+ y = m_yMargin;
+
+ int maxHeight = 0;
+
+ const wxCoord widthTool = IsVertical() ? m_defaultHeight : m_defaultWidth;
+ wxCoord margin = IsVertical() ? m_xMargin : m_yMargin;
+ wxCoord *pCur = IsVertical() ? &y : &x;
+
+ // calculate the positions of all elements
+ for ( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+ node;
+ node = node->GetNext() )
+ {
+ wxButtonToolBarTool *tool = (wxButtonToolBarTool *) node->GetData();
+
+ 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);
+
+ 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;
+
+ maxHeight = wxMax(maxHeight, sz.y);
+ }
+
+ *pCur += (w + GetToolPacking());
+ }
+ 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;
+
+ maxHeight = wxMax(maxHeight, size.y);
+ }
+ *pCur += margin;
+ }
+
+ // calculate the total toolbar size
+ m_maxWidth = x + 2*m_xMargin;
+ m_maxHeight = maxHeight + 2*m_yMargin;
+}
+
+wxSize wxButtonToolBar::DoGetBestClientSize() const
+{
+ return wxSize(m_maxWidth, m_maxHeight);
+}
+
+// receives button commands
+void wxButtonToolBar::OnCommand(wxCommandEvent& event)
+{
+ wxButtonToolBarTool* tool = (wxButtonToolBarTool*) FindById(event.GetId());
+ if (!tool)
+ {
+ event.Skip();
+ return;
+ }
+
+ // TODO: handle toggle items
+ OnLeftClick(event.GetId(), false);
+}
+
+#endif // wxUSE_TOOLBAR && wxUSE_BMPBUTTON
+