The old code used the current toolbar size instead of determining its best size for some strange reason and this resulted in toolbar remaining of tiny (1 pixel) height at least under wxGTK. Fix this by simply using the best size of the toolbar. Closes #11606. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@63629 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
441 lines
11 KiB
C++
441 lines
11 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/generic/toolbkg.cpp
|
|
// Purpose: generic implementation of wxToolbook
|
|
// Author: Julian Smart
|
|
// Modified by:
|
|
// Created: 2006-01-29
|
|
// RCS-ID: $Id$
|
|
// Copyright: (c) 2006 Julian Smart
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
#ifdef __BORLANDC__
|
|
#pragma hdrstop
|
|
#endif
|
|
|
|
#if wxUSE_TOOLBOOK
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/icon.h"
|
|
#include "wx/settings.h"
|
|
#include "wx/toolbar.h"
|
|
#endif
|
|
|
|
#include "wx/imaglist.h"
|
|
#include "wx/sysopt.h"
|
|
#include "wx/toolbook.h"
|
|
|
|
#if defined(__WXMAC__) && wxUSE_TOOLBAR && wxUSE_BMPBUTTON
|
|
#include "wx/generic/buttonbar.h"
|
|
#endif
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// various wxWidgets macros
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// check that the page index is valid
|
|
#define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount())
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// event table
|
|
// ----------------------------------------------------------------------------
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxToolbook, wxBookCtrlBase)
|
|
|
|
wxDEFINE_EVENT( wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGING, wxBookCtrlEvent );
|
|
wxDEFINE_EVENT( wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGED, wxBookCtrlEvent );
|
|
|
|
BEGIN_EVENT_TABLE(wxToolbook, wxBookCtrlBase)
|
|
EVT_SIZE(wxToolbook::OnSize)
|
|
EVT_TOOL_RANGE(1, 50, wxToolbook::OnToolSelected)
|
|
EVT_IDLE(wxToolbook::OnIdle)
|
|
END_EVENT_TABLE()
|
|
|
|
// ============================================================================
|
|
// wxToolbook implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxToolbook creation
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxToolbook::Init()
|
|
{
|
|
m_selection = wxNOT_FOUND;
|
|
m_needsRealizing = false;
|
|
}
|
|
|
|
bool wxToolbook::Create(wxWindow *parent,
|
|
wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
long style,
|
|
const wxString& name)
|
|
{
|
|
if ( (style & wxBK_ALIGN_MASK) == wxBK_DEFAULT )
|
|
style |= wxBK_TOP;
|
|
|
|
// no border for this control
|
|
style &= ~wxBORDER_MASK;
|
|
style |= wxBORDER_NONE;
|
|
|
|
if ( !wxControl::Create(parent, id, pos, size, style,
|
|
wxDefaultValidator, name) )
|
|
return false;
|
|
|
|
int tbFlags = wxTB_TEXT | wxTB_FLAT | wxBORDER_NONE;
|
|
if ( (style & (wxBK_LEFT | wxBK_RIGHT)) != 0 )
|
|
tbFlags |= wxTB_VERTICAL;
|
|
else
|
|
tbFlags |= wxTB_HORIZONTAL;
|
|
|
|
if ( style & wxTBK_HORZ_LAYOUT )
|
|
tbFlags |= wxTB_HORZ_LAYOUT;
|
|
|
|
// TODO: make more configurable
|
|
|
|
#if defined(__WXMAC__) && wxUSE_TOOLBAR && wxUSE_BMPBUTTON
|
|
if (style & wxTBK_BUTTONBAR)
|
|
{
|
|
m_bookctrl = new wxButtonToolBar
|
|
(
|
|
this,
|
|
wxID_ANY,
|
|
wxDefaultPosition,
|
|
wxDefaultSize,
|
|
tbFlags
|
|
);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
m_bookctrl = new wxToolBar
|
|
(
|
|
this,
|
|
wxID_ANY,
|
|
wxDefaultPosition,
|
|
wxDefaultSize,
|
|
tbFlags | wxTB_NODIVIDER
|
|
);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxToolbook geometry management
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxSize wxToolbook::GetControllerSize() const
|
|
{
|
|
const wxSize sizeClient = GetClientSize(),
|
|
sizeToolBar = GetToolBar()->GetBestSize();
|
|
|
|
wxSize size;
|
|
|
|
if ( IsVertical() )
|
|
{
|
|
size.x = sizeClient.x;
|
|
size.y = sizeToolBar.y;
|
|
}
|
|
else // left/right aligned
|
|
{
|
|
size.x = sizeToolBar.x;
|
|
size.y = sizeClient.y;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
void wxToolbook::OnSize(wxSizeEvent& event)
|
|
{
|
|
if (m_needsRealizing)
|
|
Realize();
|
|
|
|
wxBookCtrlBase::OnSize(event);
|
|
}
|
|
|
|
wxSize wxToolbook::CalcSizeFromPage(const wxSize& sizePage) const
|
|
{
|
|
// we need to add the size of the list control and the border between
|
|
const wxSize sizeToolBar = GetControllerSize();
|
|
|
|
wxSize size = sizePage;
|
|
if ( IsVertical() )
|
|
{
|
|
size.y += sizeToolBar.y + GetInternalBorder();
|
|
}
|
|
else // left/right aligned
|
|
{
|
|
size.x += sizeToolBar.x + GetInternalBorder();
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// accessing the pages
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool wxToolbook::SetPageText(size_t n, const wxString& strText)
|
|
{
|
|
// Assume tool ids start from 1
|
|
wxToolBarToolBase* tool = GetToolBar()->FindById(n + 1);
|
|
if (tool)
|
|
{
|
|
tool->SetLabel(strText);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
wxString wxToolbook::GetPageText(size_t n) const
|
|
{
|
|
wxToolBarToolBase* tool = GetToolBar()->FindById(n + 1);
|
|
if (tool)
|
|
return tool->GetLabel();
|
|
else
|
|
return wxEmptyString;
|
|
}
|
|
|
|
int wxToolbook::GetPageImage(size_t WXUNUSED(n)) const
|
|
{
|
|
wxFAIL_MSG( wxT("wxToolbook::GetPageImage() not implemented") );
|
|
|
|
return wxNOT_FOUND;
|
|
}
|
|
|
|
bool wxToolbook::SetPageImage(size_t n, int imageId)
|
|
{
|
|
wxASSERT( GetImageList() != NULL );
|
|
if (!GetImageList())
|
|
return false;
|
|
|
|
wxToolBarToolBase* tool = GetToolBar()->FindById(n + 1);
|
|
if (tool)
|
|
{
|
|
// Find the image list index for this tool
|
|
wxBitmap bitmap = GetImageList()->GetBitmap(imageId);
|
|
tool->SetNormalBitmap(bitmap);
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// image list stuff
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxToolbook::SetImageList(wxImageList *imageList)
|
|
{
|
|
wxBookCtrlBase::SetImageList(imageList);
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// selection
|
|
// ----------------------------------------------------------------------------
|
|
|
|
int wxToolbook::GetSelection() const
|
|
{
|
|
return m_selection;
|
|
}
|
|
|
|
wxBookCtrlEvent* wxToolbook::CreatePageChangingEvent() const
|
|
{
|
|
return new wxBookCtrlEvent(wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGING, m_windowId);
|
|
}
|
|
|
|
void wxToolbook::MakeChangedEvent(wxBookCtrlEvent &event)
|
|
{
|
|
event.SetEventType(wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGED);
|
|
}
|
|
|
|
void wxToolbook::UpdateSelectedPage(size_t newsel)
|
|
{
|
|
m_selection = newsel;
|
|
GetToolBar()->ToggleTool(newsel + 1, true);
|
|
}
|
|
|
|
// Not part of the wxBookctrl API, but must be called in OnIdle or
|
|
// by application to realize the toolbar and select the initial page.
|
|
void wxToolbook::Realize()
|
|
{
|
|
if (m_needsRealizing)
|
|
{
|
|
m_needsRealizing = false;
|
|
|
|
GetToolBar()->SetToolBitmapSize(m_maxBitmapSize);
|
|
|
|
GetToolBar()->Realize();
|
|
}
|
|
|
|
if (m_selection == -1)
|
|
m_selection = 0;
|
|
|
|
if (GetPageCount() > 0)
|
|
{
|
|
int sel = m_selection;
|
|
m_selection = -1;
|
|
SetSelection(sel);
|
|
}
|
|
|
|
DoSize();
|
|
}
|
|
|
|
int wxToolbook::HitTest(const wxPoint& pt, long *flags) const
|
|
{
|
|
int pagePos = wxNOT_FOUND;
|
|
|
|
if ( flags )
|
|
*flags = wxBK_HITTEST_NOWHERE;
|
|
|
|
// convert from wxToolbook coordinates to wxToolBar ones
|
|
const wxToolBarBase * const tbar = GetToolBar();
|
|
const wxPoint tbarPt = tbar->ScreenToClient(ClientToScreen(pt));
|
|
|
|
// is the point over the toolbar?
|
|
if ( wxRect(tbar->GetSize()).Contains(tbarPt) )
|
|
{
|
|
const wxToolBarToolBase * const
|
|
tool = tbar->FindToolForPosition(tbarPt.x, tbarPt.y);
|
|
|
|
if ( tool )
|
|
{
|
|
pagePos = tbar->GetToolPos(tool->GetId());
|
|
if ( flags )
|
|
*flags = wxBK_HITTEST_ONICON | wxBK_HITTEST_ONLABEL;
|
|
}
|
|
}
|
|
else // not over the toolbar
|
|
{
|
|
if ( flags && GetPageRect().Contains(pt) )
|
|
*flags |= wxBK_HITTEST_ONPAGE;
|
|
}
|
|
|
|
return pagePos;
|
|
}
|
|
|
|
void wxToolbook::OnIdle(wxIdleEvent& event)
|
|
{
|
|
if (m_needsRealizing)
|
|
Realize();
|
|
event.Skip();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// adding/removing the pages
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool wxToolbook::InsertPage(size_t n,
|
|
wxWindow *page,
|
|
const wxString& text,
|
|
bool bSelect,
|
|
int imageId)
|
|
{
|
|
if ( !wxBookCtrlBase::InsertPage(n, page, text, bSelect, imageId) )
|
|
return false;
|
|
|
|
m_needsRealizing = true;
|
|
|
|
wxASSERT(GetImageList() != NULL);
|
|
|
|
if (!GetImageList())
|
|
return false;
|
|
|
|
// TODO: make sure all platforms can convert between icon and bitmap,
|
|
// and/or test whether the image is a bitmap or an icon.
|
|
#ifdef __WXMAC__
|
|
wxBitmap bitmap = GetImageList()->GetBitmap(imageId);
|
|
#else
|
|
// On Windows, we can lose information by using GetBitmap, so extract icon instead
|
|
wxIcon icon = GetImageList()->GetIcon(imageId);
|
|
wxBitmap bitmap;
|
|
bitmap.CopyFromIcon(icon);
|
|
#endif
|
|
|
|
m_maxBitmapSize.x = wxMax(bitmap.GetWidth(), m_maxBitmapSize.x);
|
|
m_maxBitmapSize.y = wxMax(bitmap.GetHeight(), m_maxBitmapSize.y);
|
|
|
|
GetToolBar()->SetToolBitmapSize(m_maxBitmapSize);
|
|
GetToolBar()->AddRadioTool(n + 1, text, bitmap, wxNullBitmap, text);
|
|
|
|
if (bSelect)
|
|
{
|
|
GetToolBar()->ToggleTool(n, true);
|
|
m_selection = n;
|
|
}
|
|
else
|
|
page->Hide();
|
|
|
|
InvalidateBestSize();
|
|
return true;
|
|
}
|
|
|
|
wxWindow *wxToolbook::DoRemovePage(size_t page)
|
|
{
|
|
const size_t page_count = GetPageCount();
|
|
wxWindow *win = wxBookCtrlBase::DoRemovePage(page);
|
|
|
|
if ( win )
|
|
{
|
|
GetToolBar()->DeleteTool(page + 1);
|
|
|
|
if (m_selection >= (int)page)
|
|
{
|
|
// force new sel valid if possible
|
|
int sel = m_selection - 1;
|
|
if (page_count == 1)
|
|
sel = wxNOT_FOUND;
|
|
else if ((page_count == 2) || (sel == -1))
|
|
sel = 0;
|
|
|
|
// force sel invalid if deleting current page - don't try to hide it
|
|
m_selection = (m_selection == (int)page) ? wxNOT_FOUND : m_selection - 1;
|
|
|
|
if ((sel != wxNOT_FOUND) && (sel != m_selection))
|
|
SetSelection(sel);
|
|
}
|
|
}
|
|
|
|
return win;
|
|
}
|
|
|
|
|
|
bool wxToolbook::DeleteAllPages()
|
|
{
|
|
GetToolBar()->ClearTools();
|
|
return wxBookCtrlBase::DeleteAllPages();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxToolbook events
|
|
// ----------------------------------------------------------------------------
|
|
|
|
void wxToolbook::OnToolSelected(wxCommandEvent& event)
|
|
{
|
|
const int selNew = event.GetId() - 1;
|
|
|
|
if ( selNew == m_selection )
|
|
{
|
|
// this event can only come from our own Select(m_selection) below
|
|
// which we call when the page change is vetoed, so we should simply
|
|
// ignore it
|
|
return;
|
|
}
|
|
|
|
SetSelection(selNew);
|
|
|
|
// change wasn't allowed, return to previous state
|
|
if (m_selection != selNew)
|
|
{
|
|
GetToolBar()->ToggleTool(m_selection, false);
|
|
}
|
|
}
|
|
|
|
#endif // wxUSE_TOOLBOOK
|