]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/notebook.cpp
tree ctrl sorting shouldn't crash when items don't have data
[wxWidgets.git] / src / gtk / notebook.cpp
CommitLineData
53b28675
RR
1/////////////////////////////////////////////////////////////////////////////
2// Name: notebook.cpp
3// Purpose:
4// Author: Robert Roebling
a81258be 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling, Vadim Zeitlin
ff829f3f 7// Licence: wxWindows licence
53b28675
RR
8/////////////////////////////////////////////////////////////////////////////
9
10#ifdef __GNUG__
11#pragma implementation "notebook.h"
12#endif
13
14#include "wx/notebook.h"
15#include "wx/panel.h"
16#include "wx/utils.h"
17#include "wx/imaglist.h"
30dea054 18#include "wx/intl.h"
4bf58c62 19#include "wx/log.h"
83624f79
RR
20
21#include "gdk/gdk.h"
22#include "gtk/gtk.h"
23#include "wx/gtk/win_gtk.h"
b292e2f5
RR
24#include "gdk/gdkkeysyms.h"
25
acfd422a
RR
26//-----------------------------------------------------------------------------
27// idle system
28//-----------------------------------------------------------------------------
29
30extern void wxapp_install_idle_handler();
31extern bool g_isIdle;
32
b292e2f5
RR
33//-----------------------------------------------------------------------------
34// data
35//-----------------------------------------------------------------------------
36
37extern bool g_blockEventsOnDrag;
53b28675 38
2e563988
RR
39//-----------------------------------------------------------------------------
40// debug
41//-----------------------------------------------------------------------------
42
43#ifdef __WXDEBUG__
44
45extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
46
47#endif
48
219f895a
RR
49//-----------------------------------------------------------------------------
50// wxNotebookPage
51//-----------------------------------------------------------------------------
52
53class wxNotebookPage: public wxObject
54{
55public:
56 wxNotebookPage()
57 {
58 m_id = -1;
59 m_text = "";
60 m_image = -1;
c67daf87
UR
61 m_page = (GtkNotebookPage *) NULL;
62 m_client = (wxWindow *) NULL;
63 m_parent = (GtkNotebook *) NULL;
24d20a8f 64 m_box = (GtkWidget *) NULL;
ef44a621 65 m_added = FALSE;
ff7b1510 66 }
219f895a 67
3eb78d7e
RR
68 /*
69 mark page as "added' to the notebook, return FALSE if the page was
70 already added
f861258f
VZ
71 */
72
ef44a621
VZ
73 bool Add()
74 {
75 if ( WasAdded() )
76 return FALSE;
77
78 m_added = TRUE;
79 return TRUE;
80 }
81
82 bool WasAdded() const { return m_added; }
83
219f895a
RR
84 int m_id;
85 wxString m_text;
86 int m_image;
87 GtkNotebookPage *m_page;
88 GtkLabel *m_label;
89 wxWindow *m_client;
90 GtkNotebook *m_parent;
24d20a8f 91 GtkWidget *m_box; // in which the label and image are packed
ef44a621
VZ
92
93private:
94 bool m_added;
219f895a
RR
95};
96
ff829f3f 97//-----------------------------------------------------------------------------
5b011451 98// "switch_page"
ff829f3f
VZ
99//-----------------------------------------------------------------------------
100
219f895a
RR
101static void gtk_notebook_page_change_callback(GtkNotebook *WXUNUSED(widget),
102 GtkNotebookPage *WXUNUSED(page),
ff829f3f
VZ
103 gint nPage,
104 gpointer data)
105{
acfd422a
RR
106 if (g_isIdle) wxapp_install_idle_handler();
107
b292e2f5 108 wxNotebook *notebook = (wxNotebook *)data;
ff829f3f 109
b292e2f5 110 int old = notebook->GetSelection();
ff829f3f 111
b292e2f5 112 // TODO: emulate PAGE_CHANGING event
ef44a621 113
b292e2f5
RR
114 wxNotebookEvent event( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
115 notebook->GetId(), nPage, old );
116 event.SetEventObject( notebook );
117 notebook->GetEventHandler()->ProcessEvent( event );
ff829f3f
VZ
118}
119
5b011451
RR
120//-----------------------------------------------------------------------------
121// "size_allocate"
122//-----------------------------------------------------------------------------
123
33d0b396 124static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
caac5181 125{
acfd422a 126 if (g_isIdle) wxapp_install_idle_handler();
e208b369 127
b292e2f5
RR
128 if ((win->m_x == alloc->x) &&
129 (win->m_y == alloc->y) &&
130 (win->m_width == alloc->width) &&
131 (win->m_height == alloc->height))
132 {
58dea4b0 133 return;
b292e2f5 134 }
2b07d713 135
b292e2f5 136 win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height );
f861258f 137
b292e2f5
RR
138 if (win->GetAutoLayout()) win->Layout();
139}
140
141//-----------------------------------------------------------------------------
142// "key_press_event"
143//-----------------------------------------------------------------------------
144
f861258f 145static gint
b292e2f5
RR
146gtk_notebook_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxNotebook *notebook )
147{
acfd422a
RR
148 if (g_isIdle) wxapp_install_idle_handler();
149
b292e2f5
RR
150 if (g_blockEventsOnDrag) return FALSE;
151
152 if (!notebook->HasVMT()) return FALSE;
f861258f 153
b98d804b
RR
154 /* this code makes jumping down from the handles of the notebooks
155 to the actual items in the visible notebook page possible with
156 the down-arrow key */
b292e2f5
RR
157
158 if (gdk_event->keyval != GDK_Down) return FALSE;
f861258f 159
b292e2f5 160 if (notebook != notebook->FindFocus()) return FALSE;
f861258f 161
b292e2f5 162 if (notebook->m_pages.GetCount() == 0) return FALSE;
f861258f 163
b292e2f5 164 wxNode *node = notebook->m_pages.Nth( notebook->GetSelection() );
f861258f 165
b292e2f5 166 if (!node) return FALSE;
f861258f 167
b292e2f5 168 wxNotebookPage *page = (wxNotebookPage*) node->Data();
f861258f 169
b292e2f5
RR
170 // don't let others the key event
171 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" );
f861258f 172
b292e2f5 173 page->m_client->SetFocus();
f861258f 174
b292e2f5 175 return TRUE;
ff7b1510 176}
caac5181 177
6ca41e57
RR
178//-----------------------------------------------------------------------------
179// InsertChild callback for wxNotebook
180//-----------------------------------------------------------------------------
181
182static void wxInsertChildInNotebook( wxNotebook* parent, wxWindow* child )
183{
b292e2f5 184 wxNotebookPage *page = new wxNotebookPage();
6ca41e57 185
b292e2f5 186 page->m_id = parent->GetPageCount();
6ca41e57 187
b292e2f5
RR
188 page->m_box = gtk_hbox_new (FALSE, 0);
189 gtk_container_border_width(GTK_CONTAINER(page->m_box), 2);
6ca41e57 190
b292e2f5 191 GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
ef44a621 192
b292e2f5
RR
193 page->m_client = child;
194 gtk_notebook_append_page( notebook, child->m_widget, page->m_box );
6ca41e57 195
b292e2f5 196 page->m_page = (GtkNotebookPage*) (g_list_last(notebook->children)->data);
6ca41e57 197
b292e2f5 198 page->m_parent = notebook;
6ca41e57 199
b292e2f5
RR
200 gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate",
201 GTK_SIGNAL_FUNC(gtk_page_size_callback), (gpointer)child );
6ca41e57 202
b019151f 203 wxASSERT_MSG( page->m_page, _T("Notebook page creation error") );
6ca41e57 204
b292e2f5 205 parent->m_pages.Append( page );
6ca41e57
RR
206}
207
53b28675
RR
208//-----------------------------------------------------------------------------
209// wxNotebook
210//-----------------------------------------------------------------------------
211
53b28675
RR
212IMPLEMENT_DYNAMIC_CLASS(wxNotebook,wxControl)
213
b98d804b
RR
214BEGIN_EVENT_TABLE(wxNotebook, wxControl)
215 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
216END_EVENT_TABLE()
f861258f 217
ff829f3f 218void wxNotebook::Init()
53b28675 219{
b292e2f5
RR
220 m_imageList = (wxImageList *) NULL;
221 m_pages.DeleteContents( TRUE );
222 m_idHandler = 0;
ff829f3f
VZ
223}
224
225wxNotebook::wxNotebook()
226{
b292e2f5 227 Init();
ff7b1510 228}
53b28675 229
debe6624 230wxNotebook::wxNotebook( wxWindow *parent, wxWindowID id,
53b28675 231 const wxPoint& pos, const wxSize& size,
debe6624 232 long style, const wxString& name )
53b28675 233{
b292e2f5
RR
234 Init();
235 Create( parent, id, pos, size, style, name );
ff7b1510 236}
53b28675 237
ff829f3f 238wxNotebook::~wxNotebook()
53b28675 239{
b292e2f5
RR
240 // don't generate change page events any more
241 if (m_idHandler != 0)
242 gtk_signal_disconnect(GTK_OBJECT(m_widget), m_idHandler);
ff829f3f 243
b292e2f5 244 DeleteAllPages();
ff7b1510 245}
53b28675 246
debe6624 247bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
53b28675 248 const wxPoint& pos, const wxSize& size,
debe6624 249 long style, const wxString& name )
53b28675 250{
b292e2f5
RR
251 m_needParent = TRUE;
252 m_acceptsFocus = TRUE;
253 m_insertCallback = (wxInsertChildFunction)wxInsertChildInNotebook;
254
255 PreCreation( parent, id, pos, size, style, name );
ff829f3f 256
b292e2f5 257 m_widget = gtk_notebook_new();
53b28675 258
2e563988
RR
259#ifdef __WXDEBUG__
260 debug_focus_in( m_widget, _T("wxNotebook::m_widget"), name );
261#endif
262
b292e2f5 263 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
caac5181 264
b292e2f5 265 m_idHandler = gtk_signal_connect (
ff829f3f
VZ
266 GTK_OBJECT(m_widget), "switch_page",
267 GTK_SIGNAL_FUNC(gtk_notebook_page_change_callback),
ba4e3652 268 (gpointer)this );
ff829f3f 269
b292e2f5 270 m_parent->AddChild( this );
6ca41e57 271
b292e2f5 272 (m_parent->m_insertCallback)( m_parent, this );
ef44a621 273
b292e2f5
RR
274 gtk_signal_connect( GTK_OBJECT(m_widget), "key_press_event",
275 GTK_SIGNAL_FUNC(gtk_notebook_key_press_callback), (gpointer)this );
ff829f3f 276
b292e2f5 277 PostCreation();
ff829f3f 278
b292e2f5
RR
279 Show( TRUE );
280
281 return TRUE;
ff7b1510 282}
53b28675 283
ff829f3f 284int wxNotebook::GetSelection() const
53b28675 285{
b019151f 286 wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") );
53b28675 287
b292e2f5 288 if (m_pages.Number() == 0) return -1;
ff829f3f 289
b292e2f5
RR
290 GtkNotebookPage *g_page = GTK_NOTEBOOK(m_widget)->cur_page;
291 if (!g_page) return -1;
53b28675 292
b292e2f5 293 wxNotebookPage *page = (wxNotebookPage *) NULL;
ef44a621 294
b292e2f5
RR
295 wxNode *node = m_pages.First();
296 while (node)
ba4e3652 297 {
b292e2f5
RR
298 page = (wxNotebookPage*)node->Data();
299
300 if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL))
301 {
302 // page->m_page is NULL directly after gtk_notebook_append. gtk emits
303 // "switch_page" then and we ask for GetSelection() in the handler for
304 // "switch_page". otherwise m_page should never be NULL. all this
305 // might also be wrong.
306 break;
307 }
308 node = node->Next();
ba4e3652 309 }
53b28675 310
b019151f 311 wxCHECK_MSG( node != NULL, -1, _T("wxNotebook: no selection?") );
ff829f3f 312
b292e2f5 313 return page->m_id;
ff7b1510 314}
53b28675 315
ff829f3f 316int wxNotebook::GetPageCount() const
53b28675 317{
b292e2f5
RR
318 // count only the pages which were already added to the notebook for MSW
319 // compatibility (and, in fact, this behaviour makes more sense anyhow
320 // because only the added pages are shown)
f861258f 321
b292e2f5
RR
322 int n = 0;
323 for ( wxNode *node = m_pages.First(); node; node = node->Next() )
324 {
325 wxNotebookPage *page = (wxNotebookPage*)node->Data();
f861258f 326
b292e2f5
RR
327 if (page->WasAdded()) n++;
328 }
ef44a621 329
b292e2f5 330 return n;
ff7b1510 331}
53b28675 332
ff829f3f 333int wxNotebook::GetRowCount() const
53b28675 334{
b292e2f5 335 return 1;
ff7b1510 336}
53b28675 337
ff829f3f 338wxString wxNotebook::GetPageText( int page ) const
53b28675 339{
b019151f 340 wxCHECK_MSG( m_widget != NULL, _T(""), _T("invalid notebook") );
ef44a621 341
b292e2f5
RR
342 wxNotebookPage* nb_page = GetNotebookPage(page);
343 if (nb_page)
344 return nb_page->m_text;
345 else
346 return "";
ff7b1510 347}
53b28675 348
ff829f3f 349int wxNotebook::GetPageImage( int page ) const
53b28675 350{
b019151f 351 wxCHECK_MSG( m_widget != NULL, 0, _T("invalid notebook") );
a81258be 352
b292e2f5
RR
353 wxNotebookPage* nb_page = GetNotebookPage(page);
354 if (nb_page)
355 return nb_page->m_image;
356 else
357 return 0;
ff7b1510 358}
53b28675 359
8aadf227 360wxNotebookPage* wxNotebook::GetNotebookPage(int page) const
53b28675 361{
b019151f 362 wxCHECK_MSG( m_widget != NULL, (wxNotebookPage*)NULL, _T("invalid notebook") );
a81258be 363
b292e2f5 364 wxNotebookPage *nb_page = (wxNotebookPage *) NULL;
53b28675 365
b292e2f5
RR
366 wxNode *node = m_pages.First();
367 while (node)
368 {
369 nb_page = (wxNotebookPage*)node->Data();
370 if (nb_page->m_id == page)
371 return nb_page;
372 node = node->Next();
373 }
ff829f3f 374
b019151f 375 wxFAIL_MSG( _T("Notebook page not found!") );
ff829f3f 376
b292e2f5 377 return (wxNotebookPage *) NULL;
ff7b1510 378}
53b28675 379
ff829f3f 380int wxNotebook::SetSelection( int page )
53b28675 381{
b019151f 382 wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") );
a81258be 383
3eb78d7e
RR
384 int selOld = GetSelection();
385 wxNotebookPage* nb_page = GetNotebookPage(page);
ef44a621 386
3eb78d7e 387 if (!nb_page) return -1;
ff829f3f 388
3eb78d7e
RR
389 int page_num = 0;
390 GList *child = GTK_NOTEBOOK(m_widget)->children;
391 while (child)
392 {
393 if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
394 page_num++;
395 child = child->next;
396 }
ff829f3f 397
3eb78d7e 398 if (!child) return -1;
ff829f3f 399
3eb78d7e 400 gtk_notebook_set_page( GTK_NOTEBOOK(m_widget), page_num );
ff829f3f 401
3eb78d7e 402 return selOld;
ff7b1510 403}
53b28675 404
5b011451 405void wxNotebook::AdvanceSelection( bool bForward )
ff829f3f 406{
b019151f 407 wxCHECK_RET( m_widget != NULL, _T("invalid notebook") );
a81258be 408
3eb78d7e
RR
409 int sel = GetSelection();
410 int max = GetPageCount();
ff829f3f 411
3eb78d7e
RR
412 if (bForward)
413 SetSelection( sel == max ? 0 : sel + 1 );
414 else
b98d804b 415 SetSelection( sel == 0 ? max-1 : sel - 1 );
ff829f3f
VZ
416}
417
53b28675
RR
418void wxNotebook::SetImageList( wxImageList* imageList )
419{
3eb78d7e 420 m_imageList = imageList;
ff7b1510 421}
53b28675 422
ff829f3f 423bool wxNotebook::SetPageText( int page, const wxString &text )
53b28675 424{
b019151f 425 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") );
a81258be 426
3eb78d7e 427 wxNotebookPage* nb_page = GetNotebookPage(page);
ef44a621 428
f861258f 429 wxCHECK_MSG( nb_page, FALSE, _T("SetPageText: invalid page index") );
ff829f3f 430
3eb78d7e 431 nb_page->m_text = text;
ff829f3f 432
b019151f 433 gtk_label_set(nb_page->m_label, nb_page->m_text.mbc_str());
3eb78d7e
RR
434
435 return TRUE;
ff7b1510 436}
53b28675 437
debe6624 438bool wxNotebook::SetPageImage( int page, int image )
53b28675 439{
3eb78d7e 440 /* HvdH 28-12-98: now it works, but it's a bit of a kludge */
f861258f 441
3eb78d7e 442 wxNotebookPage* nb_page = GetNotebookPage(page);
ef44a621 443
3eb78d7e 444 if (!nb_page) return FALSE;
f861258f 445
3eb78d7e
RR
446 /* Optimization posibility: return immediately if image unchanged.
447 * Not enabled because it may break existing (stupid) code that
448 * manipulates the imagelist to cycle images */
f861258f 449
3eb78d7e 450 /* if (image == nb_page->m_image) return TRUE; */
f861258f
VZ
451
452 /* For different cases:
3eb78d7e
RR
453 1) no image -> no image
454 2) image -> no image
455 3) no image -> image
456 4) image -> image */
f861258f 457
3eb78d7e
RR
458 if (image == -1 && nb_page->m_image == -1)
459 return TRUE; /* Case 1): Nothing to do. */
f861258f 460
bbe0af5b 461 GtkWidget *pixmapwid = (GtkWidget*) NULL;
f861258f
VZ
462
463 if (nb_page->m_image != -1)
3eb78d7e
RR
464 {
465 /* Case 2) or 4). There is already an image in the gtkhbox. Let's find it */
f861258f 466
3eb78d7e
RR
467 GList *child = gtk_container_children(GTK_CONTAINER(nb_page->m_box));
468 while (child)
469 {
f861258f 470 if (GTK_IS_PIXMAP(child->data))
3eb78d7e
RR
471 {
472 pixmapwid = GTK_WIDGET(child->data);
473 break;
474 }
475 child = child->next;
476 }
f861258f 477
3eb78d7e 478 /* We should have the pixmap widget now */
f861258f
VZ
479 wxASSERT(pixmapwid != NULL);
480
481 if (image == -1)
3eb78d7e
RR
482 {
483 /* If there's no new widget, just remove the old from the box */
484 gtk_container_remove(GTK_CONTAINER(nb_page->m_box), pixmapwid);
485 nb_page->m_image = -1;
53b28675 486
3eb78d7e
RR
487 return TRUE; /* Case 2) */
488 }
489 }
f861258f 490
3eb78d7e
RR
491 /* Only cases 3) and 4) left */
492 wxASSERT( m_imageList != NULL ); /* Just in case */
f861258f 493
3eb78d7e
RR
494 /* Construct the new pixmap */
495 const wxBitmap *bmp = m_imageList->GetBitmap(image);
496 GdkPixmap *pixmap = bmp->GetPixmap();
497 GdkBitmap *mask = (GdkBitmap*) NULL;
f861258f 498 if ( bmp->GetMask() )
3eb78d7e
RR
499 {
500 mask = bmp->GetMask()->GetBitmap();
501 }
f861258f
VZ
502
503 if (pixmapwid == NULL)
3eb78d7e
RR
504 {
505 /* Case 3) No old pixmap. Create a new one and prepend it to the hbox */
506 pixmapwid = gtk_pixmap_new (pixmap, mask );
f861258f 507
3eb78d7e
RR
508 /* CHECKME: Are these pack flags okay? */
509 gtk_box_pack_start(GTK_BOX(nb_page->m_box), pixmapwid, FALSE, FALSE, 3);
510 gtk_widget_show(pixmapwid);
511 }
f861258f 512 else
3eb78d7e
RR
513 {
514 /* Case 4) Simply replace the pixmap */
515 gtk_pixmap_set(GTK_PIXMAP(pixmapwid), pixmap, mask);
516 }
f861258f 517
3eb78d7e 518 nb_page->m_image = image;
53b28675 519
3eb78d7e 520 return TRUE;
ff7b1510 521}
53b28675
RR
522
523void wxNotebook::SetPageSize( const wxSize &WXUNUSED(size) )
524{
b019151f 525 wxFAIL_MSG( _T("wxNotebook::SetPageSize not implemented") );
ff7b1510 526}
53b28675
RR
527
528void wxNotebook::SetPadding( const wxSize &WXUNUSED(padding) )
529{
b019151f 530 wxFAIL_MSG( _T("wxNotebook::SetPadding not implemented") );
ff7b1510 531}
53b28675 532
ca8b28f2
JS
533void wxNotebook::SetTabSize(const wxSize& sz)
534{
b019151f 535 wxFAIL_MSG( _T("wxNotebook::SetTabSize not implemented") );
ca8b28f2
JS
536}
537
ff829f3f 538bool wxNotebook::DeleteAllPages()
53b28675 539{
b019151f 540 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") );
a81258be 541
3eb78d7e
RR
542 wxNode *page_node = m_pages.First();
543 while (page_node)
544 {
545 wxNotebookPage *page = (wxNotebookPage*)page_node->Data();
ff829f3f 546
3eb78d7e 547 DeletePage( page->m_id );
ff829f3f 548
3eb78d7e
RR
549 page_node = m_pages.First();
550 }
ff829f3f 551
3eb78d7e 552 return TRUE;
ff7b1510 553}
53b28675 554
ff829f3f 555bool wxNotebook::DeletePage( int page )
53b28675 556{
3eb78d7e
RR
557 wxNotebookPage* nb_page = GetNotebookPage(page);
558 if (!nb_page) return FALSE;
53b28675 559
3eb78d7e
RR
560 int page_num = 0;
561 GList *child = GTK_NOTEBOOK(m_widget)->children;
562 while (child)
563 {
564 if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
565 page_num++;
566 child = child->next;
567 }
53010e52 568
b019151f 569 wxCHECK_MSG( child != NULL, FALSE, _T("illegal notebook index") );
ff829f3f 570
3eb78d7e 571 delete nb_page->m_client;
ff829f3f 572
3eb78d7e 573 m_pages.DeleteObject( nb_page );
fed46e72 574
5549fa65
RR
575 /* adjust the notebook page numbers so that
576 m_id reflects the current position, Daniel Paull */
577 int count = 0;
578 wxNode *node = m_pages.First();
579 wxNotebookPage *pagePtr = (wxNotebookPage *) NULL;
580 while (node)
581 {
582 pagePtr = (wxNotebookPage*)node->Data();
583 pagePtr->m_id = count++;
584 node = node->Next();
585 }
586
3eb78d7e 587 return TRUE;
fed46e72
RR
588}
589
590bool wxNotebook::RemovePage( int page )
591{
3eb78d7e
RR
592 wxNotebookPage* nb_page = GetNotebookPage(page);
593 if (!nb_page) return FALSE;
fed46e72 594
3eb78d7e
RR
595 int page_num = 0;
596 GList *child = GTK_NOTEBOOK(m_widget)->children;
597 while (child)
598 {
599 if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
600 page_num++;
601 child = child->next;
602 }
fed46e72 603
b019151f 604 wxCHECK_MSG( child != NULL, FALSE, _T("illegal notebook index") );
fed46e72 605
3eb78d7e 606 gtk_notebook_remove_page( GTK_NOTEBOOK(m_widget), page_num );
ff829f3f 607
3eb78d7e 608 m_pages.DeleteObject( nb_page );
ff829f3f 609
3eb78d7e 610 return TRUE;
ff7b1510 611}
53b28675 612
ff829f3f 613bool wxNotebook::AddPage(wxWindow* win, const wxString& text,
b292e2f5 614 bool select, int imageId)
53b28675 615{
b019151f 616 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") );
a81258be 617
3eb78d7e
RR
618 /* we've created the notebook page in AddChild(). Now we just have to set
619 the caption for the page and set the others parameters. */
8aadf227 620
3eb78d7e 621 wxNotebookPage *page = (wxNotebookPage *) NULL;
53b28675 622
3eb78d7e
RR
623 wxNode *node = m_pages.First();
624 while (node)
625 {
626 page = (wxNotebookPage*)node->Data();
627 if ( page->m_client == win ) break;
628 node = node->Next();
629 }
8aadf227 630
3eb78d7e 631 wxCHECK_MSG( page != NULL, FALSE,
b019151f 632 _T("Can't add a page whose parent is not the notebook!") );
ef44a621 633
3eb78d7e 634 wxCHECK_MSG( page->Add(), FALSE,
b019151f 635 _T("Can't add the same page twice to a notebook.") );
ff829f3f 636
3eb78d7e 637 if (imageId != -1)
e4a81a2e 638 {
3eb78d7e
RR
639 wxASSERT( m_imageList != NULL );
640
641 const wxBitmap *bmp = m_imageList->GetBitmap(imageId);
642 GdkPixmap *pixmap = bmp->GetPixmap();
643 GdkBitmap *mask = (GdkBitmap*) NULL;
644 if ( bmp->GetMask() )
645 {
646 mask = bmp->GetMask()->GetBitmap();
647 }
e4a81a2e 648
3eb78d7e 649 GtkWidget *pixmapwid = gtk_pixmap_new (pixmap, mask );
24d20a8f 650
3eb78d7e 651 gtk_box_pack_start(GTK_BOX(page->m_box), pixmapwid, FALSE, FALSE, 3);
24d20a8f 652
3eb78d7e
RR
653 gtk_widget_show(pixmapwid);
654 }
24d20a8f 655
3eb78d7e
RR
656 /* then set the attributes */
657 page->m_text = text;
b019151f 658 if (page->m_text.IsEmpty()) page->m_text = _T("");
3eb78d7e 659 page->m_image = imageId;
b019151f 660 page->m_label = (GtkLabel *)gtk_label_new(page->m_text.mbc_str());
3eb78d7e 661 gtk_box_pack_end( GTK_BOX(page->m_box), (GtkWidget *)page->m_label, FALSE, FALSE, 3);
741fd203 662
3eb78d7e
RR
663 /* @@@: what does this do? do we still need it?
664 gtk_misc_set_alignment(GTK_MISC(page->m_label), 0.0, 0.5); */
741fd203 665
3eb78d7e 666 gtk_widget_show((GtkWidget *)page->m_label);
741fd203 667
3eb78d7e 668 if (select) SetSelection( GetPageCount()-1 );
ff829f3f 669
3eb78d7e 670 return TRUE;
ff7b1510 671}
53b28675 672
b98d804b
RR
673void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
674{
f861258f 675 if (event.IsWindowChange())
b98d804b 676 AdvanceSelection( event.GetDirection() );
f861258f 677 else
b98d804b
RR
678 event.Skip();
679}
680
ff829f3f 681wxWindow *wxNotebook::GetPage( int page ) const
53b28675 682{
b019151f 683 wxCHECK_MSG( m_widget != NULL, (wxWindow*) NULL, _T("invalid notebook") );
a81258be 684
b292e2f5
RR
685 wxNotebookPage* nb_page = GetNotebookPage(page);
686 if (!nb_page)
687 return (wxWindow *) NULL;
688 else
689 return nb_page->m_client;
ff7b1510 690}
53b28675 691
5a8c929e 692// override these 2 functions to do nothing: everything is done in OnSize
e3e65dac 693void wxNotebook::SetConstraintSizes( bool WXUNUSED(recurse) )
5a8c929e 694{
b292e2f5
RR
695 // don't set the sizes of the pages - their correct size is not yet known
696 wxControl::SetConstraintSizes(FALSE);
5a8c929e
VZ
697}
698
e3e65dac 699bool wxNotebook::DoPhase( int WXUNUSED(nPhase) )
5a8c929e 700{
b292e2f5 701 return TRUE;
5a8c929e
VZ
702}
703
58614078 704void wxNotebook::ApplyWidgetStyle()
a81258be 705{
b292e2f5
RR
706 SetWidgetStyle();
707 gtk_widget_set_style( m_widget, m_widgetStyle );
a81258be
RR
708}
709
58d1c1ae
RR
710bool wxNotebook::IsOwnGtkWindow( GdkWindow *window )
711{
712 return ((m_widget->window == window) ||
713 (GTK_NOTEBOOK(m_widget)->panel == window));
714}
715
53b28675 716//-----------------------------------------------------------------------------
ff829f3f 717// wxNotebookEvent
53b28675
RR
718//-----------------------------------------------------------------------------
719
92976ab6 720IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
5b011451 721