wxWidgets/samples/widgets/notebook.cpp

548 lines
16 KiB
C++
Raw Normal View History

/////////////////////////////////////////////////////////////////////////////
// Program: wxWidgets Widgets Sample
// Name: notebook.cpp
// Purpose: Part of the widgets sample showing wxNotebook
// Author: Vadim Zeitlin
// Created: 06.04.01
// Id: $Id$
// Copyright: (c) 2001 Vadim Zeitlin
// License: wxWindows license
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// for compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_NOTEBOOK
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/app.h"
#include "wx/log.h"
#include "wx/button.h"
#include "wx/checkbox.h"
#include "wx/combobox.h"
#include "wx/radiobox.h"
#include "wx/statbox.h"
#include "wx/textctrl.h"
#include "wx/dynarray.h"
#endif
#include "wx/sizer.h"
#include "wx/notebook.h"
#include "wx/artprov.h"
#include "widgets.h"
#include "icons/notebook.xpm"
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// control ids
enum
{
NotebookPage_Reset = 100,
NotebookPage_SelectPage,
NotebookPage_AddPage,
NotebookPage_InsertPage,
NotebookPage_RemovePage,
NotebookPage_DeleteAll,
NotebookPage_InsertText,
NotebookPage_RemoveText,
NotebookPage_SelectText,
NotebookPage_NumPagesText,
NotebookPage_CurSelectText,
NotebookPage_Notebook
};
// notebook orientations
enum Orient
{
Orient_Top,
Orient_Bottom,
Orient_Left,
Orient_Right,
Orient_Max
};
// ----------------------------------------------------------------------------
// NotebookWidgetsPage
// ----------------------------------------------------------------------------
class NotebookWidgetsPage : public WidgetsPage
{
public:
NotebookWidgetsPage(wxBookCtrl *book, wxImageList *imaglist);
virtual ~NotebookWidgetsPage();
virtual wxControl *GetWidget() const { return m_notebook; }
protected:
// event handlers
void OnPageChanging(wxNotebookEvent& event);
void OnPageChanged(wxNotebookEvent& event);
void OnButtonReset(wxCommandEvent& event);
void OnButtonDeleteAll(wxCommandEvent& event);
void OnButtonSelectPage(wxCommandEvent& event);
void OnButtonAddPage(wxCommandEvent& event);
void OnButtonInsertPage(wxCommandEvent& event);
void OnButtonRemovePage(wxCommandEvent& event);
void OnCheckOrRadioBox(wxCommandEvent& event);
void OnUpdateUINumPagesText(wxUpdateUIEvent& event);
void OnUpdateUICurSelectText(wxUpdateUIEvent& event);
void OnUpdateUISelectButton(wxUpdateUIEvent& event);
void OnUpdateUIInsertButton(wxUpdateUIEvent& event);
void OnUpdateUIRemoveButton(wxUpdateUIEvent& event);
void OnUpdateUIResetButton(wxUpdateUIEvent& event);
// reset the wxNotebook parameters
void Reset();
// (re)create the wxNotebook
void CreateNotebook();
// create or destroy the image list
void CreateImageList();
// create a new page
wxWindow *CreateNewPage();
// get the image index for the new page
int GetIconIndex() const;
// get the numeric value of text ctrl
int GetTextValue(wxTextCtrl *text) const;
// is the value in range?
bool IsValidValue(int val) const
{ return (val >= 0) && (val < (int) m_notebook->GetPageCount()); }
// the controls
// ------------
// the check/radio boxes for styles
wxCheckBox *m_chkImages;
wxRadioBox *m_radioOrient;
// the text controls containing input for various commands
wxTextCtrl *m_textInsert,
*m_textRemove,
*m_textSelect;
// the notebook itself and the sizer it is in
wxNotebook *m_notebook;
wxSizer *m_sizerNotebook;
// thei mage list for our notebook
wxImageList *m_imageList;
private:
DECLARE_EVENT_TABLE()
DECLARE_WIDGETS_PAGE(NotebookWidgetsPage)
};
// ----------------------------------------------------------------------------
// event tables
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(NotebookWidgetsPage, WidgetsPage)
EVT_BUTTON(NotebookPage_Reset, NotebookWidgetsPage::OnButtonReset)
EVT_BUTTON(NotebookPage_SelectPage, NotebookWidgetsPage::OnButtonSelectPage)
EVT_BUTTON(NotebookPage_AddPage, NotebookWidgetsPage::OnButtonAddPage)
EVT_BUTTON(NotebookPage_InsertPage, NotebookWidgetsPage::OnButtonInsertPage)
EVT_BUTTON(NotebookPage_RemovePage, NotebookWidgetsPage::OnButtonRemovePage)
EVT_BUTTON(NotebookPage_DeleteAll, NotebookWidgetsPage::OnButtonDeleteAll)
EVT_UPDATE_UI(NotebookPage_NumPagesText, NotebookWidgetsPage::OnUpdateUINumPagesText)
EVT_UPDATE_UI(NotebookPage_CurSelectText, NotebookWidgetsPage::OnUpdateUICurSelectText)
EVT_UPDATE_UI(NotebookPage_SelectPage, NotebookWidgetsPage::OnUpdateUISelectButton)
EVT_UPDATE_UI(NotebookPage_InsertPage, NotebookWidgetsPage::OnUpdateUIInsertButton)
EVT_UPDATE_UI(NotebookPage_RemovePage, NotebookWidgetsPage::OnUpdateUIRemoveButton)
EVT_NOTEBOOK_PAGE_CHANGING(wxID_ANY, NotebookWidgetsPage::OnPageChanging)
EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, NotebookWidgetsPage::OnPageChanged)
EVT_CHECKBOX(wxID_ANY, NotebookWidgetsPage::OnCheckOrRadioBox)
EVT_RADIOBOX(wxID_ANY, NotebookWidgetsPage::OnCheckOrRadioBox)
END_EVENT_TABLE()
// ============================================================================
// implementation
// ============================================================================
IMPLEMENT_WIDGETS_PAGE(NotebookWidgetsPage, _T("Notebook"));
NotebookWidgetsPage::NotebookWidgetsPage(wxBookCtrl *book,
wxImageList *imaglist)
: WidgetsPage(book)
{
imaglist->Add(wxBitmap(notebook_xpm));
// init everything
m_chkImages = NULL;
m_imageList = NULL;
m_notebook = (wxNotebook *)NULL;
m_sizerNotebook = (wxSizer *)NULL;
wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL);
// left pane
wxStaticBox *box = new wxStaticBox(this, wxID_ANY, _T("&Set style"));
// must be in sync with Orient enum
wxString orientations[] =
{
_T("&top"),
_T("&bottom"),
_T("&left"),
_T("&right"),
};
wxASSERT_MSG( WXSIZEOF(orientations) == Orient_Max,
_T("forgot to update something") );
m_chkImages = new wxCheckBox(this, wxID_ANY, _T("Show &images"));
m_radioOrient = new wxRadioBox(this, wxID_ANY, _T("&Tab orientation"),
wxDefaultPosition, wxDefaultSize,
WXSIZEOF(orientations), orientations,
1, wxRA_SPECIFY_COLS);
wxSizer *sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
sizerLeft->Add(m_chkImages, 0, wxALL, 5);
sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
sizerLeft->Add(m_radioOrient, 0, wxALL, 5);
wxButton *btn = new wxButton(this, NotebookPage_Reset, _T("&Reset"));
sizerLeft->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
// middle pane
wxStaticBox *box2 = new wxStaticBox(this, wxID_ANY, _T("&Contents"));
wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
wxTextCtrl *text;
wxSizer *sizerRow = CreateSizerWithTextAndLabel(_T("Number of pages: "),
NotebookPage_NumPagesText,
&text);
text->SetEditable(false);
sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
sizerRow = CreateSizerWithTextAndLabel(_T("Current selection: "),
NotebookPage_CurSelectText,
&text);
text->SetEditable(false);
sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
sizerRow = CreateSizerWithTextAndButton(NotebookPage_SelectPage,
_T("&Select page"),
NotebookPage_SelectText,
&m_textSelect);
sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
btn = new wxButton(this, NotebookPage_AddPage, _T("&Add page"));
sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
sizerRow = CreateSizerWithTextAndButton(NotebookPage_InsertPage,
_T("&Insert page at"),
NotebookPage_InsertText,
&m_textInsert);
sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
sizerRow = CreateSizerWithTextAndButton(NotebookPage_RemovePage,
_T("&Remove page"),
NotebookPage_RemoveText,
&m_textRemove);
sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
btn = new wxButton(this, NotebookPage_DeleteAll, _T("&Delete All"));
sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
// right pane
wxSizer *sizerRight = new wxBoxSizer(wxHORIZONTAL);
m_notebook = new wxNotebook(this, NotebookPage_Notebook);
sizerRight->Add(m_notebook, 1, wxGROW | wxALL, 5);
sizerRight->SetMinSize(150, 0);
m_sizerNotebook = sizerRight; // save it to modify it later
// the 3 panes panes compose the window
sizerTop->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
sizerTop->Add(sizerMiddle, 0, wxGROW | wxALL, 10);
sizerTop->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
// final initializations
Reset();
CreateImageList();
SetSizer(sizerTop);
sizerTop->Fit(this);
}
NotebookWidgetsPage::~NotebookWidgetsPage()
{
delete m_imageList;
}
// ----------------------------------------------------------------------------
// operations
// ----------------------------------------------------------------------------
void NotebookWidgetsPage::Reset()
{
m_chkImages->SetValue(true);
m_radioOrient->SetSelection(Orient_Top);
}
void NotebookWidgetsPage::CreateImageList()
{
if ( m_chkImages->GetValue() )
{
if ( !m_imageList )
{
// create a dummy image list with a few icons
m_imageList = new wxImageList(32, 32);
wxSize size(32, 32);
m_imageList->Add(wxArtProvider::GetIcon(wxART_INFORMATION, wxART_OTHER, size));
m_imageList->Add(wxArtProvider::GetIcon(wxART_QUESTION, wxART_OTHER, size));
m_imageList->Add(wxArtProvider::GetIcon(wxART_WARNING, wxART_OTHER, size));
m_imageList->Add(wxArtProvider::GetIcon(wxART_ERROR, wxART_OTHER, size));
}
m_notebook->SetImageList(m_imageList);
}
else // no images
{
if ( m_imageList )
{
delete m_imageList;
m_imageList = NULL;
}
}
// because of the bug in wxMSW we can't use SetImageList(NULL) - although
// it would be logical if this removed the image list from notebook, under
// MSW it crashes instead
}
void NotebookWidgetsPage::CreateNotebook()
{
int flags;
switch ( m_radioOrient->GetSelection() )
{
default:
wxFAIL_MSG( _T("unknown notebook orientation") );
// fall through
case Orient_Top:
flags = wxNB_TOP;
break;
case Orient_Bottom:
flags = wxNB_BOTTOM;
break;
case Orient_Left:
flags = wxNB_LEFT;
break;
case Orient_Right:
flags = wxNB_RIGHT;
break;
}
wxNotebook *old_note = m_notebook;
m_notebook = new wxNotebook(this, NotebookPage_Notebook,
wxDefaultPosition, wxDefaultSize,
flags);
CreateImageList();
if ( old_note )
{
const int sel = old_note->GetSelection();
const int count = old_note->GetPageCount();
// recreate the pages
for ( int n = 0; n < count; n++ )
{
m_notebook->AddPage(CreateNewPage(),
old_note->GetPageText(n),
false,
m_chkImages->GetValue() ?
GetIconIndex() : -1);
}
m_sizerNotebook->Detach( old_note );
delete old_note;
// restore selection
if ( sel != -1 )
{
m_notebook->SetSelection(sel);
}
}
m_sizerNotebook->Add(m_notebook, 1, wxGROW | wxALL, 5);
m_sizerNotebook->Layout();
}
// ----------------------------------------------------------------------------
// helpers
// ----------------------------------------------------------------------------
int NotebookWidgetsPage::GetTextValue(wxTextCtrl *text) const
{
long pos;
if ( !text->GetValue().ToLong(&pos) )
pos = -1;
return (int)pos;
}
int NotebookWidgetsPage::GetIconIndex() const
{
if ( m_imageList )
{
int nImages = m_imageList->GetImageCount();
if ( nImages > 0 )
{
return m_notebook->GetPageCount() % nImages;
}
}
return -1;
}
wxWindow *NotebookWidgetsPage::CreateNewPage()
{
return new wxTextCtrl(m_notebook, wxID_ANY, _T("I'm a notebook page"));
}
// ----------------------------------------------------------------------------
// event handlers
// ----------------------------------------------------------------------------
void NotebookWidgetsPage::OnButtonReset(wxCommandEvent& WXUNUSED(event))
{
Reset();
CreateNotebook();
}
void NotebookWidgetsPage::OnButtonDeleteAll(wxCommandEvent& WXUNUSED(event))
{
m_notebook->DeleteAllPages();
}
void NotebookWidgetsPage::OnButtonSelectPage(wxCommandEvent& WXUNUSED(event))
{
int pos = GetTextValue(m_textSelect);
wxCHECK_RET( IsValidValue(pos), _T("button should be disabled") );
m_notebook->SetSelection(pos);
}
void NotebookWidgetsPage::OnButtonAddPage(wxCommandEvent& WXUNUSED(event))
{
m_notebook->AddPage(CreateNewPage(), _T("Added page"), false,
GetIconIndex());
}
void NotebookWidgetsPage::OnButtonInsertPage(wxCommandEvent& WXUNUSED(event))
{
int pos = GetTextValue(m_textInsert);
wxCHECK_RET( IsValidValue(pos), _T("button should be disabled") );
m_notebook->InsertPage(pos, CreateNewPage(), _T("Inserted page"), false,
GetIconIndex());
}
void NotebookWidgetsPage::OnButtonRemovePage(wxCommandEvent& WXUNUSED(event))
{
int pos = GetTextValue(m_textRemove);
wxCHECK_RET( IsValidValue(pos), _T("button should be disabled") );
m_notebook->DeletePage(pos);
}
void NotebookWidgetsPage::OnUpdateUISelectButton(wxUpdateUIEvent& event)
{
event.Enable( IsValidValue(GetTextValue(m_textSelect)) );
}
void NotebookWidgetsPage::OnUpdateUIInsertButton(wxUpdateUIEvent& event)
{
event.Enable( IsValidValue(GetTextValue(m_textInsert)) );
}
void NotebookWidgetsPage::OnUpdateUIRemoveButton(wxUpdateUIEvent& event)
{
event.Enable( IsValidValue(GetTextValue(m_textRemove)) );
}
void NotebookWidgetsPage::OnUpdateUIResetButton(wxUpdateUIEvent& event)
{
event.Enable( !m_chkImages->GetValue() ||
m_radioOrient->GetSelection() != wxNB_TOP );
}
void NotebookWidgetsPage::OnUpdateUINumPagesText(wxUpdateUIEvent& event)
{
event.SetText( wxString::Format(_T("%d"), m_notebook->GetPageCount()) );
}
void NotebookWidgetsPage::OnUpdateUICurSelectText(wxUpdateUIEvent& event)
{
event.SetText( wxString::Format(_T("%d"), m_notebook->GetSelection()) );
}
void NotebookWidgetsPage::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
{
CreateNotebook();
}
void NotebookWidgetsPage::OnPageChanging(wxNotebookEvent& event)
{
wxLogMessage(_T("Notebook page changing from %d to %d (currently %d)."),
event.GetOldSelection(),
event.GetSelection(),
m_notebook->GetSelection());
event.Skip();
}
void NotebookWidgetsPage::OnPageChanged(wxNotebookEvent& event)
{
wxLogMessage(_T("Notebook page changed from %d to %d (currently %d)."),
event.GetOldSelection(),
event.GetSelection(),
m_notebook->GetSelection());
event.Skip();
}
#endif // wxUSE_NOTEBOOK