X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/93d381756808d466a91e844d4ed10600a87c7a32..dd107c50be43e8d4dbdba20df162faf119a3781c:/src/gtk/notebook.cpp diff --git a/src/gtk/notebook.cpp b/src/gtk/notebook.cpp index 1034747a3f..1bbcc15109 100644 --- a/src/gtk/notebook.cpp +++ b/src/gtk/notebook.cpp @@ -26,6 +26,13 @@ #include "wx/gtk/win_gtk.h" #include +// ---------------------------------------------------------------------------- +// events +// ---------------------------------------------------------------------------- + +DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING) + //----------------------------------------------------------------------------- // idle system //----------------------------------------------------------------------------- @@ -82,27 +89,44 @@ static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget), gint page, wxNotebook *notebook ) { + static bool s_inPageChange = FALSE; + + // are you trying to call SetSelection() from a notebook event handler? + // you shouldn't! + wxCHECK_RET( !s_inPageChange, + _T("gtk_notebook_page_change_callback reentered") ); + + s_inPageChange = TRUE; if (g_isIdle) wxapp_install_idle_handler(); int old = notebook->GetSelection(); - wxNotebookEvent event1( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, - notebook->GetId(), page, old ); - event1.SetEventObject( notebook ); + wxNotebookEvent eventChanging( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, + notebook->GetId(), page, old ); + eventChanging.SetEventObject( notebook ); - if ((notebook->GetEventHandler()->ProcessEvent( event1 )) && - !event1.IsAllowed() ) + if ( (notebook->GetEventHandler()->ProcessEvent(eventChanging)) && + !eventChanging.IsAllowed() ) { /* program doesn't allow the page change */ - gtk_signal_emit_stop_by_name( GTK_OBJECT(notebook->m_widget), "switch_page" ); - return; + gtk_signal_emit_stop_by_name( GTK_OBJECT(notebook->m_widget), + "switch_page" ); + } + else // change allowed + { + // make wxNotebook::GetSelection() return the correct (i.e. consistent + // with wxNotebookEvent::GetSelection()) value even though the page is + // not really changed in GTK+ + notebook->m_selection = page; + + wxNotebookEvent eventChanged( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, + notebook->GetId(), page, old ); + eventChanged.SetEventObject( notebook ); + notebook->GetEventHandler()->ProcessEvent( eventChanged ); } - wxNotebookEvent event2( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, - notebook->GetId(), page, old ); - event2.SetEventObject( notebook ); - notebook->GetEventHandler()->ProcessEvent( event2 ); + s_inPageChange = FALSE; } //----------------------------------------------------------------------------- @@ -178,6 +202,7 @@ static gint gtk_notebook_key_press_callback( GtkWidget *widget, GdkEventKey *gdk /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ event.SetDirection( (gdk_event->keyval == GDK_Tab) ); /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ + event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) ); event.SetCurrentFocus( win ); if (!page->m_client->GetEventHandler()->ProcessEvent( event )) { @@ -213,8 +238,10 @@ END_EVENT_TABLE() void wxNotebook::Init() { m_imageList = (wxImageList *) NULL; + m_ownsImageList = FALSE; m_pages.DeleteContents( TRUE ); - m_lastSelection = -1; + m_selection = -1; + m_themeEnabled = TRUE; } wxNotebook::wxNotebook() @@ -237,6 +264,7 @@ wxNotebook::~wxNotebook() GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer) this ); DeleteAllPages(); + if (m_ownsImageList) delete m_imageList; } bool wxNotebook::Create(wxWindow *parent, wxWindowID id, @@ -294,15 +322,24 @@ int wxNotebook::GetSelection() const { wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid notebook") ); - GList *pages = GTK_NOTEBOOK(m_widget)->children; - - if (g_list_length(pages) == 0) return -1; + if ( m_selection == -1 ) + { + GList *pages = GTK_NOTEBOOK(m_widget)->children; - GtkNotebook *notebook = GTK_NOTEBOOK(m_widget); + if (g_list_length(pages) != 0) + { + GtkNotebook *notebook = GTK_NOTEBOOK(m_widget); - if (notebook->cur_page == NULL) return m_lastSelection; + gpointer cur = notebook->cur_page; + if ( cur != NULL ) + { + wxConstCast(this, wxNotebook)->m_selection = + g_list_index( pages, cur ); + } + } + } - return g_list_index( pages, (gpointer)(notebook->cur_page) ); + return m_selection; } int wxNotebook::GetPageCount() const @@ -356,6 +393,8 @@ int wxNotebook::SetSelection( int page ) int selOld = GetSelection(); + // cache the selection + m_selection = page; gtk_notebook_set_page( GTK_NOTEBOOK(m_widget), page ); wxGtkNotebookPage* g_page = GetNotebookPage( page ); @@ -386,7 +425,15 @@ void wxNotebook::AdvanceSelection( bool forward ) void wxNotebook::SetImageList( wxImageList* imageList ) { + if (m_ownsImageList) delete m_imageList; m_imageList = imageList; + m_ownsImageList = FALSE; +} + +void wxNotebook::AssignImageList( wxImageList* imageList ) +{ + SetImageList(imageList); + m_ownsImageList = TRUE; } bool wxNotebook::SetPageText( int page, const wxString &text ) @@ -517,17 +564,23 @@ bool wxNotebook::DeleteAllPages() bool wxNotebook::DeletePage( int page ) { wxGtkNotebookPage* nb_page = GetNotebookPage(page); - if (!nb_page) return FALSE; + wxCHECK_MSG( nb_page, FALSE, _T("invalid page in wxNotebook::DeletePage") ); - /* GTK sets GtkNotebook.cur_page to NULL before sending - the switvh page event */ - m_lastSelection = GetSelection(); + // GTK sets GtkNotebook.cur_page to NULL before sending the switch page + // event so we have to store the selection internally + if ( m_selection == -1 ) + { + m_selection = GetSelection(); + if ( m_selection == (int)m_pages.GetCount() - 1 ) + { + // the index will become invalid after the page is deleted + m_selection = -1; + } + } nb_page->m_client->Destroy(); m_pages.DeleteObject( nb_page ); - m_lastSelection = -1; - return TRUE; } @@ -535,8 +588,12 @@ bool wxNotebook::RemovePage( int page ) { wxGtkNotebookPage* nb_page = GetNotebookPage(page); - if (!nb_page) return FALSE; + wxCHECK_MSG( nb_page, FALSE, _T("wxNotebook::RemovePage: invalid page") ); + gtk_widget_ref( nb_page->m_client->m_widget ); + gtk_widget_unrealize( nb_page->m_client->m_widget ); + gtk_widget_unparent( nb_page->m_client->m_widget ); + gtk_notebook_remove_page( GTK_NOTEBOOK(m_widget), page ); m_pages.DeleteObject( nb_page ); @@ -556,6 +613,9 @@ bool wxNotebook::InsertPage( int position, wxNotebookPage* win, const wxString& gtk_signal_disconnect_by_func( GTK_OBJECT(m_widget), GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback), (gpointer) this ); + if (m_themeEnabled) + win->SetThemeEnabled(TRUE); + GtkNotebook *notebook = GTK_NOTEBOOK(m_widget); wxGtkNotebookPage *page = new wxGtkNotebookPage();