git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38705 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
430 lines
12 KiB
C++
430 lines
12 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// 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
|
|
|
|
// Currently, only for Mac as a toolbar replacement.
|
|
#if defined(__WXMAC__) && 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
|
|
|