--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/toolbook.h
+// Purpose: wxToolbook: wxToolBar and wxNotebook combination
+// Author: Julian Smart
+// Modified by:
+// Created: 2006-01-29
+// RCS-ID: $Id$
+// Copyright: (c) 2006 Julian Smart
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_TOOLBOOK_H_
+#define _WX_TOOLBOOK_H_
+
+#include "wx/defs.h"
+
+#if wxUSE_TOOLBOOK
+
+#include "wx/bookctrl.h"
+
+class WXDLLEXPORT wxToolBarBase;
+class WXDLLEXPORT wxCommandEvent;
+
+// ----------------------------------------------------------------------------
+// wxToolbook
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxToolbook : public wxBookCtrlBase
+{
+public:
+ wxToolbook()
+ {
+ Init();
+ }
+
+ wxToolbook(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = 0,
+ const wxString& name = wxEmptyString)
+ {
+ Init();
+
+ (void)Create(parent, id, pos, size, style, name);
+ }
+
+ // quasi ctor
+ bool Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = 0,
+ const wxString& name = wxEmptyString);
+
+
+ virtual int GetSelection() const;
+ virtual bool SetPageText(size_t n, const wxString& strText);
+ virtual wxString GetPageText(size_t n) const;
+ virtual int GetPageImage(size_t n) const;
+ virtual bool SetPageImage(size_t n, int imageId);
+ virtual wxSize CalcSizeFromPage(const wxSize& sizePage) const;
+ virtual bool InsertPage(size_t n,
+ wxWindow *page,
+ const wxString& text,
+ bool bSelect = false,
+ int imageId = -1);
+ virtual int SetSelection(size_t n);
+ virtual void SetImageList(wxImageList *imageList);
+
+ virtual bool DeleteAllPages();
+
+ wxToolBarBase* GetToolBar() const { return (wxToolBarBase*)m_bookctrl; }
+
+ // 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 Realize();
+
+protected:
+ virtual wxWindow *DoRemovePage(size_t page);
+
+ // get the size which the list control should have
+ virtual wxSize GetControllerSize() const;
+
+ // event handlers
+ void OnToolSelected(wxCommandEvent& event);
+ void OnSize(wxSizeEvent& event);
+ void OnIdle(wxIdleEvent& event);
+
+ // the currently selected page or wxNOT_FOUND if none
+ int m_selection;
+
+ // whether the toolbar needs to be realized
+ bool m_needsRealizing;
+
+ // maximum bitmap size
+ wxSize m_maxBitmapSize;
+
+private:
+ // common part of all constructors
+ void Init();
+
+ DECLARE_EVENT_TABLE()
+ DECLARE_DYNAMIC_CLASS_NO_COPY(wxToolbook)
+};
+
+// ----------------------------------------------------------------------------
+// listbook event class and related stuff
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxToolbookEvent : public wxBookCtrlBaseEvent
+{
+public:
+ wxToolbookEvent(wxEventType commandType = wxEVT_NULL, int id = 0,
+ int nSel = wxNOT_FOUND, int nOldSel = wxNOT_FOUND)
+ : wxBookCtrlBaseEvent(commandType, id, nSel, nOldSel)
+ {
+ }
+
+ wxToolbookEvent(const wxToolbookEvent& event)
+ : wxBookCtrlBaseEvent(event)
+ {
+ }
+
+ virtual wxEvent *Clone() const { return new wxToolbookEvent(*this); }
+
+private:
+ DECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxToolbookEvent)
+};
+
+extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGED;
+extern WXDLLIMPEXP_CORE const wxEventType wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGING;
+
+typedef void (wxEvtHandler::*wxToolbookEventFunction)(wxToolbookEvent&);
+
+#define wxToolbookEventHandler(func) \
+ (wxObjectEventFunction)(wxEventFunction)wxStaticCastEvent(wxToolbookEventFunction, &func)
+
+#define EVT_TOOLBOOK_PAGE_CHANGED(winid, fn) \
+ wx__DECLARE_EVT1(wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGED, winid, wxToolbookEventHandler(fn))
+
+#define EVT_TOOLBOOK_PAGE_CHANGING(winid, fn) \
+ wx__DECLARE_EVT1(wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGING, winid, wxToolbookEventHandler(fn))
+
+#endif // wxUSE_TOOLBOOK
+
+#endif // _WX_TOOLBOOK_H_
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// 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
+///////////////////////////////////////////////////////////////////////////////
+
+// ============================================================================
+// declarations
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#if wxUSE_LISTBOOK
+
+#include "wx/toolbar.h"
+#include "wx/toolbook.h"
+#include "wx/settings.h"
+#include "wx/sysopt.h"
+
+// ----------------------------------------------------------------------------
+// various wxWidgets macros
+// ----------------------------------------------------------------------------
+
+// check that the page index is valid
+#define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount())
+
+// ----------------------------------------------------------------------------
+// event table
+// ----------------------------------------------------------------------------
+
+IMPLEMENT_DYNAMIC_CLASS(wxToolbook, wxBookCtrlBase)
+IMPLEMENT_DYNAMIC_CLASS(wxToolbookEvent, wxNotifyEvent)
+
+const wxEventType wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGING = wxNewEventType();
+const wxEventType wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGED = wxNewEventType();
+const int wxID_TOOLBOOKTOOLBAR = wxNewId();
+
+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;
+
+ // TODO: make configurable
+ m_bookctrl = new wxToolBar
+ (
+ this,
+ wxID_TOOLBOOKTOOLBAR,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxTB_HORIZONTAL|wxTB_TEXT|wxTB_FLAT|wxTB_NODIVIDER
+ );
+
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+// wxToolbook geometry management
+// ----------------------------------------------------------------------------
+
+wxSize wxToolbook::GetControllerSize() const
+{
+ const wxSize sizeClient = GetClientSize(),
+ sizeBorder = m_bookctrl->GetSize() - m_bookctrl->GetClientSize(),
+ sizeToolBar = GetToolBar()->GetSize() + sizeBorder;
+
+ 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( _T("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;
+}
+
+int wxToolbook::SetSelection(size_t n)
+{
+ wxCHECK_MSG( IS_VALID_PAGE(n), wxNOT_FOUND,
+ wxT("invalid page index in wxToolbook::SetSelection()") );
+
+ const int oldSel = m_selection;
+
+ if ( int(n) != m_selection )
+ {
+ wxToolbookEvent event(wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGING, m_windowId);
+ event.SetSelection(n);
+ event.SetOldSelection(m_selection);
+ event.SetEventObject(this);
+ if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() )
+ {
+ if ( m_selection != wxNOT_FOUND )
+ m_pages[m_selection]->Hide();
+
+ wxWindow *page = m_pages[n];
+ page->SetSize(GetPageRect());
+ page->Show();
+
+ // change m_selection now to ignore the selection change event
+ m_selection = n;
+ GetToolBar()->ToggleTool(n+1, true);
+
+ // program allows the page change
+ event.SetEventType(wxEVT_COMMAND_TOOLBOOK_PAGE_CHANGED);
+ (void)GetEventHandler()->ProcessEvent(event);
+ }
+ }
+
+ return oldSel;
+}
+
+// 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)
+ {
+ GetToolBar()->SetToolBitmapSize(m_maxBitmapSize);
+
+ wxSystemOptions::SetOption(wxT("msw.remap"), 0);
+ GetToolBar()->Realize();
+ wxSystemOptions::SetOption(wxT("msw.remap"), 1);
+ }
+
+ m_needsRealizing = false;
+
+ if (m_selection == -1)
+ m_selection = 0;
+
+ if (GetPageCount() > 0)
+ {
+ int sel = m_selection;
+ m_selection = -1;
+ SetSelection(sel);
+ }
+
+ DoSize();
+}
+
+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;
+
+ // On Windows, we can lose information by using GetBitmap, so extract icon instead
+ wxIcon icon = GetImageList()->GetIcon(imageId);
+ wxBitmap bitmap;
+ bitmap.CopyFromIcon(icon);
+
+ 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