Rewrote wxNotebook, incl. PAGE_CHANGING event

and InsertPage and internal behaviour more
   like wxMSW. Leaves pixel junk sometimes...


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2554 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
1999-05-24 19:33:05 +00:00
parent 255d88eb5d
commit 587ce561e1
4 changed files with 246 additions and 432 deletions

View File

@@ -144,13 +144,19 @@ public:
bool DeletePage(int nPage); bool DeletePage(int nPage);
// remove all pages // remove all pages
bool DeleteAllPages(); bool DeleteAllPages();
// adds a new page to the notebook (it will be deleted ny the notebook, // adds a new page to the notebook (it will be deleted ny the notebook,
// don't delete it yourself). If bSelect, this page becomes active. // don't delete it yourself). If bSelect, this page becomes active.
bool AddPage(wxWindow *pPage, bool AddPage( wxWindow *win,
const wxString& strText, const wxString& strText,
bool select = FALSE, bool select = FALSE,
int imageId = -1); int imageId = -1 );
// TODO VZ: I don't know how to implement InsertPage() // the same as AddPage(), but adds it at the specified position
bool InsertPage( int position,
wxWindow *win,
const wxString& strText,
bool bSelect = FALSE,
int imageId = -1 );
// get the panel which represents the given page // get the panel which represents the given page
wxWindow *GetPage(int nPage) const; wxWindow *GetPage(int nPage) const;
@@ -174,7 +180,6 @@ public:
wxImageList* m_imageList; wxImageList* m_imageList;
wxList m_pages; wxList m_pages;
size_t m_idHandler; // the change page handler id
DECLARE_DYNAMIC_CLASS(wxNotebook) DECLARE_DYNAMIC_CLASS(wxNotebook)
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()

View File

@@ -144,13 +144,19 @@ public:
bool DeletePage(int nPage); bool DeletePage(int nPage);
// remove all pages // remove all pages
bool DeleteAllPages(); bool DeleteAllPages();
// adds a new page to the notebook (it will be deleted ny the notebook, // adds a new page to the notebook (it will be deleted ny the notebook,
// don't delete it yourself). If bSelect, this page becomes active. // don't delete it yourself). If bSelect, this page becomes active.
bool AddPage(wxWindow *pPage, bool AddPage( wxWindow *win,
const wxString& strText, const wxString& strText,
bool select = FALSE, bool select = FALSE,
int imageId = -1); int imageId = -1 );
// TODO VZ: I don't know how to implement InsertPage() // the same as AddPage(), but adds it at the specified position
bool InsertPage( int position,
wxWindow *win,
const wxString& strText,
bool bSelect = FALSE,
int imageId = -1 );
// get the panel which represents the given page // get the panel which represents the given page
wxWindow *GetPage(int nPage) const; wxWindow *GetPage(int nPage) const;
@@ -174,7 +180,6 @@ public:
wxImageList* m_imageList; wxImageList* m_imageList;
wxList m_pages; wxList m_pages;
size_t m_idHandler; // the change page handler id
DECLARE_DYNAMIC_CLASS(wxNotebook) DECLARE_DYNAMIC_CLASS(wxNotebook)
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()

View File

@@ -55,43 +55,19 @@ class wxNotebookPage: public wxObject
public: public:
wxNotebookPage() wxNotebookPage()
{ {
m_id = -1;
m_text = ""; m_text = "";
m_image = -1; m_image = -1;
m_page = (GtkNotebookPage *) NULL; m_page = (GtkNotebookPage *) NULL;
m_client = (wxWindow *) NULL; m_client = (wxWindow *) NULL;
m_parent = (GtkNotebook *) NULL;
m_box = (GtkWidget *) NULL; m_box = (GtkWidget *) NULL;
m_added = FALSE;
} }
/*
mark page as "added' to the notebook, return FALSE if the page was
already added
*/
bool Add()
{
if ( WasAdded() )
return FALSE;
m_added = TRUE;
return TRUE;
}
bool WasAdded() const { return m_added; }
int m_id;
wxString m_text; wxString m_text;
int m_image; int m_image;
GtkNotebookPage *m_page; GtkNotebookPage *m_page;
GtkLabel *m_label; GtkLabel *m_label;
wxWindow *m_client; wxWindow *m_client;
GtkNotebook *m_parent;
GtkWidget *m_box; // in which the label and image are packed GtkWidget *m_box; // in which the label and image are packed
private:
bool m_added;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -100,21 +76,30 @@ private:
static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget), static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget),
GtkNotebookPage *WXUNUSED(page), GtkNotebookPage *WXUNUSED(page),
gint nPage, gint page,
gpointer data) wxNotebook *notebook )
{ {
if (g_isIdle) wxapp_install_idle_handler(); if (g_isIdle)
wxapp_install_idle_handler();
wxNotebook *notebook = (wxNotebook *)data;
int old = notebook->GetSelection(); int old = notebook->GetSelection();
// TODO: emulate PAGE_CHANGING event wxNotebookEvent event1( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,
notebook->GetId(), page, old );
event1.SetEventObject( notebook );
wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, if ((notebook->GetEventHandler()->ProcessEvent( event1 )) &&
notebook->GetId(), nPage, old ); !event1.IsAllowed() )
event.SetEventObject( notebook ); {
notebook->GetEventHandler()->ProcessEvent( event ); /* program doesn't allow the page change */
gtk_signal_emit_stop_by_name( GTK_OBJECT(notebook->m_widget), "switch_page" );
return;
}
wxNotebookEvent event2( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
notebook->GetId(), page, old );
event2.SetEventObject( notebook );
notebook->GetEventHandler()->ProcessEvent( event2 );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -123,7 +108,8 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget),
static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win ) static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
{ {
if (g_isIdle) wxapp_install_idle_handler(); if (g_isIdle)
wxapp_install_idle_handler();
if ((win->m_x == alloc->x) && if ((win->m_x == alloc->x) &&
(win->m_y == alloc->y) && (win->m_y == alloc->y) &&
@@ -179,30 +165,9 @@ gtk_notebook_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxNo
// InsertChild callback for wxNotebook // InsertChild callback for wxNotebook
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void wxInsertChildInNotebook( wxNotebook* parent, wxWindow* child ) static void wxInsertChildInNotebook( wxNotebook* WXUNUSED(parent), wxWindow* WXUNUSED(child) )
{ {
wxNotebookPage *page = new wxNotebookPage(); /* we don't do anything here but pray */
page->m_id = parent->GetPageCount();
page->m_box = gtk_hbox_new (FALSE, 0);
gtk_container_border_width(GTK_CONTAINER(page->m_box), 2);
GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
page->m_client = child;
gtk_notebook_append_page( notebook, child->m_widget, page->m_box );
page->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
page->m_parent = notebook;
gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate",
GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child );
wxASSERT_MSG( page->m_page, _T("Notebook page creation error") );
parent->m_pages.Append( page );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -219,7 +184,6 @@ void wxNotebook::Init()
{ {
m_imageList = (wxImageList *) NULL; m_imageList = (wxImageList *) NULL;
m_pages.DeleteContents( TRUE ); m_pages.DeleteContents( TRUE );
m_idHandler = 0;
} }
wxNotebook::wxNotebook() wxNotebook::wxNotebook()
@@ -237,9 +201,9 @@ wxNotebook::wxNotebook( wxWindow *parent, wxWindowID id,
wxNotebook::~wxNotebook() wxNotebook::~wxNotebook()
{ {
// don't generate change page events any more /* don't generate change page events any more */
if (m_idHandler != 0) gtk_signal_disconnect_by_func( GTK_OBJECT(m_widget),
gtk_signal_disconnect(GTK_OBJECT(m_widget), m_idHandler); GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer) this );
DeleteAllPages(); DeleteAllPages();
} }
@@ -262,10 +226,8 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 ); gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
m_idHandler = gtk_signal_connect ( gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page",
GTK_OBJECT(m_widget), "switch_page", GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer)this );
GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback),
(gpointer)this );
m_parent->DoAddChild( this ); m_parent->DoAddChild( this );
@@ -283,49 +245,22 @@ int wxNotebook::GetSelection() const
{ {
wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") );
if (m_pages.Number() == 0) return -1; GList *pages = GTK_NOTEBOOK(m_widget)->children;
GtkNotebookPage *g_page = GTK_NOTEBOOK(m_widget)->cur_page; if (g_list_length(pages) == 0) return -1;
if (!g_page) return -1;
wxNotebookPage *page = (wxNotebookPage *) NULL; GtkNotebook *notebook = GTK_NOTEBOOK(m_widget);
wxNode *node = m_pages.First(); GtkNotebookPage *page = GTK_NOTEBOOK_PAGE( notebook->cur_page );
while (node)
{
page = (wxNotebookPage*)node->Data();
if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL)) wxCHECK_MSG( page, -1, "no notebook page selected/current" );
{
// page->m_page is NULL directly after gtk_notebook_append. gtk emits
// "switch_page" then and we ask for GetSelection() in the handler for
// "switch_page". otherwise m_page should never be NULL. all this
// might also be wrong.
break;
}
node = node->Next();
}
wxCHECK_MSG( node != NULL, -1, _T("wxNotebook: no selection?") ); return g_list_index( pages, (gpointer)page );
return page->m_id;
} }
int wxNotebook::GetPageCount() const int wxNotebook::GetPageCount() const
{ {
// count only the pages which were already added to the notebook for MSW return (int) g_list_length( GTK_NOTEBOOK(m_widget)->children );
// compatibility (and, in fact, this behaviour makes more sense anyhow
// because only the added pages are shown)
int n = 0;
for ( wxNode *node = m_pages.First(); node; node = node->Next() )
{
wxNotebookPage *page = (wxNotebookPage*)node->Data();
if (page->WasAdded()) n++;
}
return n;
} }
int wxNotebook::GetRowCount() const int wxNotebook::GetRowCount() const
@@ -346,68 +281,47 @@ wxString wxNotebook::GetPageText( int page ) const
int wxNotebook::GetPageImage( int page ) const int wxNotebook::GetPageImage( int page ) const
{ {
wxCHECK_MSG( m_widget != NULL, 0, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") );
wxNotebookPage* nb_page = GetNotebookPage(page); wxNotebookPage* nb_page = GetNotebookPage(page);
if (nb_page) if (nb_page)
return nb_page->m_image; return nb_page->m_image;
else else
return 0; return -1;
} }
wxNotebookPage* wxNotebook::GetNotebookPage(int page) const wxNotebookPage* wxNotebook::GetNotebookPage( int page ) const
{ {
wxCHECK_MSG( m_widget != NULL, (wxNotebookPage*)NULL, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, (wxNotebookPage*) NULL, _T("invalid notebook") );
wxNotebookPage *nb_page = (wxNotebookPage *) NULL; wxCHECK_MSG( page < (int)m_pages.GetCount(), (wxNotebookPage*) NULL, _T("invalid notebook index") );
wxNode *node = m_pages.First(); wxNode *node = m_pages.Nth( page );
while (node)
{
nb_page = (wxNotebookPage*)node->Data();
if (nb_page->m_id == page)
return nb_page;
node = node->Next();
}
wxFAIL_MSG( _T("Notebook page not found!") ); return (wxNotebookPage *) node->Data();
return (wxNotebookPage *) NULL;
} }
int wxNotebook::SetSelection( int page ) int wxNotebook::SetSelection( int page )
{ {
wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") );
wxCHECK_MSG( page < (int)m_pages.GetCount(), -1, _T("invalid notebook index") );
int selOld = GetSelection(); int selOld = GetSelection();
wxNotebookPage* nb_page = GetNotebookPage(page);
if (!nb_page) return -1; gtk_notebook_set_page( GTK_NOTEBOOK(m_widget), page );
int page_num = 0;
GList *child = GTK_NOTEBOOK(m_widget)->children;
while (child)
{
if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
page_num++;
child = child->next;
}
if (!child) return -1;
gtk_notebook_set_page( GTK_NOTEBOOK(m_widget), page_num );
return selOld; return selOld;
} }
void wxNotebook::AdvanceSelection( bool bForward ) void wxNotebook::AdvanceSelection( bool forward )
{ {
wxCHECK_RET( m_widget != NULL, _T("invalid notebook") ); wxCHECK_RET( m_widget != NULL, _T("invalid notebook") );
int sel = GetSelection(); int sel = GetSelection();
int max = GetPageCount(); int max = GetPageCount();
if (bForward) if (forward)
SetSelection( sel == max ? 0 : sel + 1 ); SetSelection( sel == max ? 0 : sel + 1 );
else else
SetSelection( sel == 0 ? max-1 : sel - 1 ); SetSelection( sel == 0 ? max-1 : sel - 1 );
@@ -428,7 +342,7 @@ bool wxNotebook::SetPageText( int page, const wxString &text )
nb_page->m_text = text; nb_page->m_text = text;
gtk_label_set(nb_page->m_label, nb_page->m_text.mbc_str()); gtk_label_set( nb_page->m_label, nb_page->m_text.mbc_str() );
return TRUE; return TRUE;
} }
@@ -537,15 +451,8 @@ bool wxNotebook::DeleteAllPages()
{ {
wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") );
wxNode *page_node = m_pages.First(); while (m_pages.GetCount() > 0)
while (page_node) DeletePage( m_pages.GetCount()-1 );
{
wxNotebookPage *page = (wxNotebookPage*)page_node->Data();
DeletePage( page->m_id );
page_node = m_pages.First();
}
return TRUE; return TRUE;
} }
@@ -555,82 +462,64 @@ bool wxNotebook::DeletePage( int page )
wxNotebookPage* nb_page = GetNotebookPage(page); wxNotebookPage* nb_page = GetNotebookPage(page);
if (!nb_page) return FALSE; if (!nb_page) return FALSE;
int page_num = 0; nb_page->m_client->Destroy();
GList *child = GTK_NOTEBOOK(m_widget)->children;
while (child)
{
if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
page_num++;
child = child->next;
}
wxCHECK_MSG( child != NULL, FALSE, _T("illegal notebook index") );
delete nb_page->m_client;
m_pages.DeleteObject( nb_page ); m_pages.DeleteObject( nb_page );
/* adjust the notebook page numbers so that
m_id reflects the current position, Daniel Paull */
int count = 0;
wxNode *node = m_pages.First();
wxNotebookPage *pagePtr = (wxNotebookPage *) NULL;
while (node)
{
pagePtr = (wxNotebookPage*)node->Data();
pagePtr->m_id = count++;
node = node->Next();
}
return TRUE; return TRUE;
} }
bool wxNotebook::RemovePage( int page ) bool wxNotebook::RemovePage( int page )
{ {
wxNotebookPage* nb_page = GetNotebookPage(page); wxNotebookPage* nb_page = GetNotebookPage(page);
if (!nb_page) return FALSE; if (!nb_page) return FALSE;
int page_num = 0; gtk_notebook_remove_page( GTK_NOTEBOOK(m_widget), page );
GList *child = GTK_NOTEBOOK(m_widget)->children;
while (child)
{
if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
page_num++;
child = child->next;
}
wxCHECK_MSG( child != NULL, FALSE, _T("illegal notebook index") );
gtk_notebook_remove_page( GTK_NOTEBOOK(m_widget), page_num );
m_pages.DeleteObject( nb_page ); m_pages.DeleteObject( nb_page );
return TRUE; return TRUE;
} }
bool wxNotebook::AddPage(wxWindow* win, const wxString& text, bool wxNotebook::InsertPage( int position, wxWindow* win, const wxString& text,
bool select, int imageId) bool select, int imageId )
{ {
wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") );
/* we've created the notebook page in AddChild(). Now we just have to set wxCHECK_MSG( win->GetParent() == this, FALSE,
the caption for the page and set the others parameters. */
wxNotebookPage *page = (wxNotebookPage *) NULL;
wxNode *node = m_pages.First();
while (node)
{
page = (wxNotebookPage*)node->Data();
if ( page->m_client == win ) break;
node = node->Next();
}
wxCHECK_MSG( page != NULL, FALSE,
_T("Can't add a page whose parent is not the notebook!") ); _T("Can't add a page whose parent is not the notebook!") );
wxCHECK_MSG( page->Add(), FALSE, /* don't receive switch page during addition */
_T("Can't add the same page twice to a notebook.") ); gtk_signal_disconnect_by_func( GTK_OBJECT(m_widget),
GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer) this );
GtkNotebook *notebook = GTK_NOTEBOOK(m_widget);
wxNotebookPage *page = new wxNotebookPage();
if (position < 0)
m_pages.Append( page );
else
m_pages.Insert( m_pages.Nth( position ), page );
page->m_client = win;
page->m_box = gtk_hbox_new( FALSE, 0 );
gtk_container_border_width( GTK_CONTAINER(page->m_box), 2 );
if (position < 0)
gtk_notebook_append_page( notebook, win->m_widget, page->m_box );
else
gtk_notebook_insert_page( notebook, win->m_widget, page->m_box, position );
page->m_page = GTK_NOTEBOOK_PAGE( g_list_last(notebook->children)->data );
gtk_signal_connect( GTK_OBJECT(win->m_widget), "size_allocate",
GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)win );
/* set the label image */
page->m_image = imageId;
if (imageId != -1) if (imageId != -1)
{ {
@@ -651,23 +540,36 @@ bool wxNotebook::AddPage(wxWindow* win, const wxString& text,
gtk_widget_show(pixmapwid); gtk_widget_show(pixmapwid);
} }
/* then set the attributes */ /* set the label text */
page->m_text = text; page->m_text = text;
if (page->m_text.IsEmpty()) page->m_text = _T(""); if (page->m_text.IsEmpty()) page->m_text = _T("");
page->m_image = imageId;
page->m_label = (GtkLabel *)gtk_label_new(page->m_text.mbc_str());
gtk_box_pack_end( GTK_BOX(page->m_box), (GtkWidget *)page->m_label, FALSE, FALSE, 3);
/* @@@: what does this do? do we still need it? page->m_label = GTK_LABEL( gtk_label_new(page->m_text.mbc_str()) );
gtk_misc_set_alignment(GTK_MISC(page->m_label), 0.0, 0.5); */ gtk_box_pack_end( GTK_BOX(page->m_box), GTK_WIDGET(page->m_label), FALSE, FALSE, 3 );
gtk_widget_show((GtkWidget *)page->m_label); /* show the label */
gtk_widget_show( GTK_WIDGET(page->m_label) );
if (select) SetSelection( GetPageCount()-1 ); if (select && (m_pages.GetCount() > 1))
{
if (position < 0)
SetSelection( GetPageCount()-1 );
else
SetSelection( position );
}
gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page",
GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer)this );
return TRUE; return TRUE;
} }
bool wxNotebook::AddPage(wxWindow* win, const wxString& text,
bool select, int imageId)
{
return InsertPage( -1, win, text, select, imageId );
}
void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event) void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
{ {
if (event.IsWindowChange()) if (event.IsWindowChange())

View File

@@ -55,43 +55,19 @@ class wxNotebookPage: public wxObject
public: public:
wxNotebookPage() wxNotebookPage()
{ {
m_id = -1;
m_text = ""; m_text = "";
m_image = -1; m_image = -1;
m_page = (GtkNotebookPage *) NULL; m_page = (GtkNotebookPage *) NULL;
m_client = (wxWindow *) NULL; m_client = (wxWindow *) NULL;
m_parent = (GtkNotebook *) NULL;
m_box = (GtkWidget *) NULL; m_box = (GtkWidget *) NULL;
m_added = FALSE;
} }
/*
mark page as "added' to the notebook, return FALSE if the page was
already added
*/
bool Add()
{
if ( WasAdded() )
return FALSE;
m_added = TRUE;
return TRUE;
}
bool WasAdded() const { return m_added; }
int m_id;
wxString m_text; wxString m_text;
int m_image; int m_image;
GtkNotebookPage *m_page; GtkNotebookPage *m_page;
GtkLabel *m_label; GtkLabel *m_label;
wxWindow *m_client; wxWindow *m_client;
GtkNotebook *m_parent;
GtkWidget *m_box; // in which the label and image are packed GtkWidget *m_box; // in which the label and image are packed
private:
bool m_added;
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -100,21 +76,30 @@ private:
static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget), static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget),
GtkNotebookPage *WXUNUSED(page), GtkNotebookPage *WXUNUSED(page),
gint nPage, gint page,
gpointer data) wxNotebook *notebook )
{ {
if (g_isIdle) wxapp_install_idle_handler(); if (g_isIdle)
wxapp_install_idle_handler();
wxNotebook *notebook = (wxNotebook *)data;
int old = notebook->GetSelection(); int old = notebook->GetSelection();
// TODO: emulate PAGE_CHANGING event wxNotebookEvent event1( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING,
notebook->GetId(), page, old );
event1.SetEventObject( notebook );
wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, if ((notebook->GetEventHandler()->ProcessEvent( event1 )) &&
notebook->GetId(), nPage, old ); !event1.IsAllowed() )
event.SetEventObject( notebook ); {
notebook->GetEventHandler()->ProcessEvent( event ); /* program doesn't allow the page change */
gtk_signal_emit_stop_by_name( GTK_OBJECT(notebook->m_widget), "switch_page" );
return;
}
wxNotebookEvent event2( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
notebook->GetId(), page, old );
event2.SetEventObject( notebook );
notebook->GetEventHandler()->ProcessEvent( event2 );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -123,7 +108,8 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget),
static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win ) static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
{ {
if (g_isIdle) wxapp_install_idle_handler(); if (g_isIdle)
wxapp_install_idle_handler();
if ((win->m_x == alloc->x) && if ((win->m_x == alloc->x) &&
(win->m_y == alloc->y) && (win->m_y == alloc->y) &&
@@ -179,30 +165,9 @@ gtk_notebook_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxNo
// InsertChild callback for wxNotebook // InsertChild callback for wxNotebook
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void wxInsertChildInNotebook( wxNotebook* parent, wxWindow* child ) static void wxInsertChildInNotebook( wxNotebook* WXUNUSED(parent), wxWindow* WXUNUSED(child) )
{ {
wxNotebookPage *page = new wxNotebookPage(); /* we don't do anything here but pray */
page->m_id = parent->GetPageCount();
page->m_box = gtk_hbox_new (FALSE, 0);
gtk_container_border_width(GTK_CONTAINER(page->m_box), 2);
GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
page->m_client = child;
gtk_notebook_append_page( notebook, child->m_widget, page->m_box );
page->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
page->m_parent = notebook;
gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate",
GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child );
wxASSERT_MSG( page->m_page, _T("Notebook page creation error") );
parent->m_pages.Append( page );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -219,7 +184,6 @@ void wxNotebook::Init()
{ {
m_imageList = (wxImageList *) NULL; m_imageList = (wxImageList *) NULL;
m_pages.DeleteContents( TRUE ); m_pages.DeleteContents( TRUE );
m_idHandler = 0;
} }
wxNotebook::wxNotebook() wxNotebook::wxNotebook()
@@ -237,9 +201,9 @@ wxNotebook::wxNotebook( wxWindow *parent, wxWindowID id,
wxNotebook::~wxNotebook() wxNotebook::~wxNotebook()
{ {
// don't generate change page events any more /* don't generate change page events any more */
if (m_idHandler != 0) gtk_signal_disconnect_by_func( GTK_OBJECT(m_widget),
gtk_signal_disconnect(GTK_OBJECT(m_widget), m_idHandler); GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer) this );
DeleteAllPages(); DeleteAllPages();
} }
@@ -262,10 +226,8 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 ); gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
m_idHandler = gtk_signal_connect ( gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page",
GTK_OBJECT(m_widget), "switch_page", GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer)this );
GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback),
(gpointer)this );
m_parent->DoAddChild( this ); m_parent->DoAddChild( this );
@@ -283,49 +245,22 @@ int wxNotebook::GetSelection() const
{ {
wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") );
if (m_pages.Number() == 0) return -1; GList *pages = GTK_NOTEBOOK(m_widget)->children;
GtkNotebookPage *g_page = GTK_NOTEBOOK(m_widget)->cur_page; if (g_list_length(pages) == 0) return -1;
if (!g_page) return -1;
wxNotebookPage *page = (wxNotebookPage *) NULL; GtkNotebook *notebook = GTK_NOTEBOOK(m_widget);
wxNode *node = m_pages.First(); GtkNotebookPage *page = GTK_NOTEBOOK_PAGE( notebook->cur_page );
while (node)
{
page = (wxNotebookPage*)node->Data();
if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL)) wxCHECK_MSG( page, -1, "no notebook page selected/current" );
{
// page->m_page is NULL directly after gtk_notebook_append. gtk emits
// "switch_page" then and we ask for GetSelection() in the handler for
// "switch_page". otherwise m_page should never be NULL. all this
// might also be wrong.
break;
}
node = node->Next();
}
wxCHECK_MSG( node != NULL, -1, _T("wxNotebook: no selection?") ); return g_list_index( pages, (gpointer)page );
return page->m_id;
} }
int wxNotebook::GetPageCount() const int wxNotebook::GetPageCount() const
{ {
// count only the pages which were already added to the notebook for MSW return (int) g_list_length( GTK_NOTEBOOK(m_widget)->children );
// compatibility (and, in fact, this behaviour makes more sense anyhow
// because only the added pages are shown)
int n = 0;
for ( wxNode *node = m_pages.First(); node; node = node->Next() )
{
wxNotebookPage *page = (wxNotebookPage*)node->Data();
if (page->WasAdded()) n++;
}
return n;
} }
int wxNotebook::GetRowCount() const int wxNotebook::GetRowCount() const
@@ -346,68 +281,47 @@ wxString wxNotebook::GetPageText( int page ) const
int wxNotebook::GetPageImage( int page ) const int wxNotebook::GetPageImage( int page ) const
{ {
wxCHECK_MSG( m_widget != NULL, 0, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") );
wxNotebookPage* nb_page = GetNotebookPage(page); wxNotebookPage* nb_page = GetNotebookPage(page);
if (nb_page) if (nb_page)
return nb_page->m_image; return nb_page->m_image;
else else
return 0; return -1;
} }
wxNotebookPage* wxNotebook::GetNotebookPage(int page) const wxNotebookPage* wxNotebook::GetNotebookPage( int page ) const
{ {
wxCHECK_MSG( m_widget != NULL, (wxNotebookPage*)NULL, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, (wxNotebookPage*) NULL, _T("invalid notebook") );
wxNotebookPage *nb_page = (wxNotebookPage *) NULL; wxCHECK_MSG( page < (int)m_pages.GetCount(), (wxNotebookPage*) NULL, _T("invalid notebook index") );
wxNode *node = m_pages.First(); wxNode *node = m_pages.Nth( page );
while (node)
{
nb_page = (wxNotebookPage*)node->Data();
if (nb_page->m_id == page)
return nb_page;
node = node->Next();
}
wxFAIL_MSG( _T("Notebook page not found!") ); return (wxNotebookPage *) node->Data();
return (wxNotebookPage *) NULL;
} }
int wxNotebook::SetSelection( int page ) int wxNotebook::SetSelection( int page )
{ {
wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") );
wxCHECK_MSG( page < (int)m_pages.GetCount(), -1, _T("invalid notebook index") );
int selOld = GetSelection(); int selOld = GetSelection();
wxNotebookPage* nb_page = GetNotebookPage(page);
if (!nb_page) return -1; gtk_notebook_set_page( GTK_NOTEBOOK(m_widget), page );
int page_num = 0;
GList *child = GTK_NOTEBOOK(m_widget)->children;
while (child)
{
if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
page_num++;
child = child->next;
}
if (!child) return -1;
gtk_notebook_set_page( GTK_NOTEBOOK(m_widget), page_num );
return selOld; return selOld;
} }
void wxNotebook::AdvanceSelection( bool bForward ) void wxNotebook::AdvanceSelection( bool forward )
{ {
wxCHECK_RET( m_widget != NULL, _T("invalid notebook") ); wxCHECK_RET( m_widget != NULL, _T("invalid notebook") );
int sel = GetSelection(); int sel = GetSelection();
int max = GetPageCount(); int max = GetPageCount();
if (bForward) if (forward)
SetSelection( sel == max ? 0 : sel + 1 ); SetSelection( sel == max ? 0 : sel + 1 );
else else
SetSelection( sel == 0 ? max-1 : sel - 1 ); SetSelection( sel == 0 ? max-1 : sel - 1 );
@@ -428,7 +342,7 @@ bool wxNotebook::SetPageText( int page, const wxString &text )
nb_page->m_text = text; nb_page->m_text = text;
gtk_label_set(nb_page->m_label, nb_page->m_text.mbc_str()); gtk_label_set( nb_page->m_label, nb_page->m_text.mbc_str() );
return TRUE; return TRUE;
} }
@@ -537,15 +451,8 @@ bool wxNotebook::DeleteAllPages()
{ {
wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") );
wxNode *page_node = m_pages.First(); while (m_pages.GetCount() > 0)
while (page_node) DeletePage( m_pages.GetCount()-1 );
{
wxNotebookPage *page = (wxNotebookPage*)page_node->Data();
DeletePage( page->m_id );
page_node = m_pages.First();
}
return TRUE; return TRUE;
} }
@@ -555,82 +462,64 @@ bool wxNotebook::DeletePage( int page )
wxNotebookPage* nb_page = GetNotebookPage(page); wxNotebookPage* nb_page = GetNotebookPage(page);
if (!nb_page) return FALSE; if (!nb_page) return FALSE;
int page_num = 0; nb_page->m_client->Destroy();
GList *child = GTK_NOTEBOOK(m_widget)->children;
while (child)
{
if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
page_num++;
child = child->next;
}
wxCHECK_MSG( child != NULL, FALSE, _T("illegal notebook index") );
delete nb_page->m_client;
m_pages.DeleteObject( nb_page ); m_pages.DeleteObject( nb_page );
/* adjust the notebook page numbers so that
m_id reflects the current position, Daniel Paull */
int count = 0;
wxNode *node = m_pages.First();
wxNotebookPage *pagePtr = (wxNotebookPage *) NULL;
while (node)
{
pagePtr = (wxNotebookPage*)node->Data();
pagePtr->m_id = count++;
node = node->Next();
}
return TRUE; return TRUE;
} }
bool wxNotebook::RemovePage( int page ) bool wxNotebook::RemovePage( int page )
{ {
wxNotebookPage* nb_page = GetNotebookPage(page); wxNotebookPage* nb_page = GetNotebookPage(page);
if (!nb_page) return FALSE; if (!nb_page) return FALSE;
int page_num = 0; gtk_notebook_remove_page( GTK_NOTEBOOK(m_widget), page );
GList *child = GTK_NOTEBOOK(m_widget)->children;
while (child)
{
if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
page_num++;
child = child->next;
}
wxCHECK_MSG( child != NULL, FALSE, _T("illegal notebook index") );
gtk_notebook_remove_page( GTK_NOTEBOOK(m_widget), page_num );
m_pages.DeleteObject( nb_page ); m_pages.DeleteObject( nb_page );
return TRUE; return TRUE;
} }
bool wxNotebook::AddPage(wxWindow* win, const wxString& text, bool wxNotebook::InsertPage( int position, wxWindow* win, const wxString& text,
bool select, int imageId) bool select, int imageId )
{ {
wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") ); wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") );
/* we've created the notebook page in AddChild(). Now we just have to set wxCHECK_MSG( win->GetParent() == this, FALSE,
the caption for the page and set the others parameters. */
wxNotebookPage *page = (wxNotebookPage *) NULL;
wxNode *node = m_pages.First();
while (node)
{
page = (wxNotebookPage*)node->Data();
if ( page->m_client == win ) break;
node = node->Next();
}
wxCHECK_MSG( page != NULL, FALSE,
_T("Can't add a page whose parent is not the notebook!") ); _T("Can't add a page whose parent is not the notebook!") );
wxCHECK_MSG( page->Add(), FALSE, /* don't receive switch page during addition */
_T("Can't add the same page twice to a notebook.") ); gtk_signal_disconnect_by_func( GTK_OBJECT(m_widget),
GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer) this );
GtkNotebook *notebook = GTK_NOTEBOOK(m_widget);
wxNotebookPage *page = new wxNotebookPage();
if (position < 0)
m_pages.Append( page );
else
m_pages.Insert( m_pages.Nth( position ), page );
page->m_client = win;
page->m_box = gtk_hbox_new( FALSE, 0 );
gtk_container_border_width( GTK_CONTAINER(page->m_box), 2 );
if (position < 0)
gtk_notebook_append_page( notebook, win->m_widget, page->m_box );
else
gtk_notebook_insert_page( notebook, win->m_widget, page->m_box, position );
page->m_page = GTK_NOTEBOOK_PAGE( g_list_last(notebook->children)->data );
gtk_signal_connect( GTK_OBJECT(win->m_widget), "size_allocate",
GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)win );
/* set the label image */
page->m_image = imageId;
if (imageId != -1) if (imageId != -1)
{ {
@@ -651,23 +540,36 @@ bool wxNotebook::AddPage(wxWindow* win, const wxString& text,
gtk_widget_show(pixmapwid); gtk_widget_show(pixmapwid);
} }
/* then set the attributes */ /* set the label text */
page->m_text = text; page->m_text = text;
if (page->m_text.IsEmpty()) page->m_text = _T(""); if (page->m_text.IsEmpty()) page->m_text = _T("");
page->m_image = imageId;
page->m_label = (GtkLabel *)gtk_label_new(page->m_text.mbc_str());
gtk_box_pack_end( GTK_BOX(page->m_box), (GtkWidget *)page->m_label, FALSE, FALSE, 3);
/* @@@: what does this do? do we still need it? page->m_label = GTK_LABEL( gtk_label_new(page->m_text.mbc_str()) );
gtk_misc_set_alignment(GTK_MISC(page->m_label), 0.0, 0.5); */ gtk_box_pack_end( GTK_BOX(page->m_box), GTK_WIDGET(page->m_label), FALSE, FALSE, 3 );
gtk_widget_show((GtkWidget *)page->m_label); /* show the label */
gtk_widget_show( GTK_WIDGET(page->m_label) );
if (select) SetSelection( GetPageCount()-1 ); if (select && (m_pages.GetCount() > 1))
{
if (position < 0)
SetSelection( GetPageCount()-1 );
else
SetSelection( position );
}
gtk_signal_connect( GTK_OBJECT(m_widget), "switch_page",
GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer)this );
return TRUE; return TRUE;
} }
bool wxNotebook::AddPage(wxWindow* win, const wxString& text,
bool select, int imageId)
{
return InsertPage( -1, win, text, select, imageId );
}
void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event) void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
{ {
if (event.IsWindowChange()) if (event.IsWindowChange())