]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/notebook.cpp
Fixed a minor bug in hotKey handling.
[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
a2053b27
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))
b292e2f5 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
a2053b27 152 if (!notebook->m_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
a2053b27 191 GtkNotebook *notebook = GTK_NOTEBOOK(parent->m_widget);
ef44a621 192
b292e2f5 193 page->m_client = child;
a2053b27 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
a2053b27 200 gtk_signal_connect( GTK_OBJECT(child->m_widget), "size_allocate",
b292e2f5 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
f03fc89f 270 m_parent->DoAddChild( this );
ef44a621 271
b292e2f5
RR
272 gtk_signal_connect( GTK_OBJECT(m_widget), "key_press_event",
273 GTK_SIGNAL_FUNC(gtk_notebook_key_press_callback), (gpointer)this );
ff829f3f 274
b292e2f5 275 PostCreation();
ff829f3f 276
b292e2f5
RR
277 Show( TRUE );
278
279 return TRUE;
ff7b1510 280}
53b28675 281
ff829f3f 282int wxNotebook::GetSelection() const
53b28675 283{
b019151f 284 wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") );
53b28675 285
b292e2f5 286 if (m_pages.Number() == 0) return -1;
ff829f3f 287
b292e2f5
RR
288 GtkNotebookPage *g_page = GTK_NOTEBOOK(m_widget)->cur_page;
289 if (!g_page) return -1;
53b28675 290
b292e2f5 291 wxNotebookPage *page = (wxNotebookPage *) NULL;
ef44a621 292
b292e2f5
RR
293 wxNode *node = m_pages.First();
294 while (node)
ba4e3652 295 {
b292e2f5
RR
296 page = (wxNotebookPage*)node->Data();
297
298 if ((page->m_page == g_page) || (page->m_page == (GtkNotebookPage*)NULL))
299 {
300 // page->m_page is NULL directly after gtk_notebook_append. gtk emits
301 // "switch_page" then and we ask for GetSelection() in the handler for
302 // "switch_page". otherwise m_page should never be NULL. all this
303 // might also be wrong.
304 break;
305 }
306 node = node->Next();
ba4e3652 307 }
53b28675 308
b019151f 309 wxCHECK_MSG( node != NULL, -1, _T("wxNotebook: no selection?") );
ff829f3f 310
b292e2f5 311 return page->m_id;
ff7b1510 312}
53b28675 313
ff829f3f 314int wxNotebook::GetPageCount() const
53b28675 315{
b292e2f5
RR
316 // count only the pages which were already added to the notebook for MSW
317 // compatibility (and, in fact, this behaviour makes more sense anyhow
318 // because only the added pages are shown)
f861258f 319
b292e2f5
RR
320 int n = 0;
321 for ( wxNode *node = m_pages.First(); node; node = node->Next() )
322 {
323 wxNotebookPage *page = (wxNotebookPage*)node->Data();
f861258f 324
b292e2f5
RR
325 if (page->WasAdded()) n++;
326 }
ef44a621 327
b292e2f5 328 return n;
ff7b1510 329}
53b28675 330
ff829f3f 331int wxNotebook::GetRowCount() const
53b28675 332{
b292e2f5 333 return 1;
ff7b1510 334}
53b28675 335
ff829f3f 336wxString wxNotebook::GetPageText( int page ) const
53b28675 337{
b019151f 338 wxCHECK_MSG( m_widget != NULL, _T(""), _T("invalid notebook") );
ef44a621 339
b292e2f5
RR
340 wxNotebookPage* nb_page = GetNotebookPage(page);
341 if (nb_page)
342 return nb_page->m_text;
343 else
344 return "";
ff7b1510 345}
53b28675 346
ff829f3f 347int wxNotebook::GetPageImage( int page ) const
53b28675 348{
b019151f 349 wxCHECK_MSG( m_widget != NULL, 0, _T("invalid notebook") );
a81258be 350
b292e2f5
RR
351 wxNotebookPage* nb_page = GetNotebookPage(page);
352 if (nb_page)
353 return nb_page->m_image;
354 else
355 return 0;
ff7b1510 356}
53b28675 357
8aadf227 358wxNotebookPage* wxNotebook::GetNotebookPage(int page) const
53b28675 359{
b019151f 360 wxCHECK_MSG( m_widget != NULL, (wxNotebookPage*)NULL, _T("invalid notebook") );
a81258be 361
b292e2f5 362 wxNotebookPage *nb_page = (wxNotebookPage *) NULL;
53b28675 363
b292e2f5
RR
364 wxNode *node = m_pages.First();
365 while (node)
366 {
367 nb_page = (wxNotebookPage*)node->Data();
368 if (nb_page->m_id == page)
369 return nb_page;
370 node = node->Next();
371 }
ff829f3f 372
b019151f 373 wxFAIL_MSG( _T("Notebook page not found!") );
ff829f3f 374
b292e2f5 375 return (wxNotebookPage *) NULL;
ff7b1510 376}
53b28675 377
ff829f3f 378int wxNotebook::SetSelection( int page )
53b28675 379{
b019151f 380 wxCHECK_MSG( m_widget != NULL, -1, _T("invalid notebook") );
a81258be 381
3eb78d7e
RR
382 int selOld = GetSelection();
383 wxNotebookPage* nb_page = GetNotebookPage(page);
ef44a621 384
3eb78d7e 385 if (!nb_page) return -1;
ff829f3f 386
3eb78d7e
RR
387 int page_num = 0;
388 GList *child = GTK_NOTEBOOK(m_widget)->children;
389 while (child)
390 {
391 if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
392 page_num++;
393 child = child->next;
394 }
ff829f3f 395
3eb78d7e 396 if (!child) return -1;
ff829f3f 397
3eb78d7e 398 gtk_notebook_set_page( GTK_NOTEBOOK(m_widget), page_num );
ff829f3f 399
3eb78d7e 400 return selOld;
ff7b1510 401}
53b28675 402
5b011451 403void wxNotebook::AdvanceSelection( bool bForward )
ff829f3f 404{
b019151f 405 wxCHECK_RET( m_widget != NULL, _T("invalid notebook") );
a81258be 406
3eb78d7e
RR
407 int sel = GetSelection();
408 int max = GetPageCount();
ff829f3f 409
3eb78d7e
RR
410 if (bForward)
411 SetSelection( sel == max ? 0 : sel + 1 );
412 else
b98d804b 413 SetSelection( sel == 0 ? max-1 : sel - 1 );
ff829f3f
VZ
414}
415
53b28675
RR
416void wxNotebook::SetImageList( wxImageList* imageList )
417{
3eb78d7e 418 m_imageList = imageList;
ff7b1510 419}
53b28675 420
ff829f3f 421bool wxNotebook::SetPageText( int page, const wxString &text )
53b28675 422{
b019151f 423 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") );
a81258be 424
3eb78d7e 425 wxNotebookPage* nb_page = GetNotebookPage(page);
ef44a621 426
f861258f 427 wxCHECK_MSG( nb_page, FALSE, _T("SetPageText: invalid page index") );
ff829f3f 428
3eb78d7e 429 nb_page->m_text = text;
ff829f3f 430
b019151f 431 gtk_label_set(nb_page->m_label, nb_page->m_text.mbc_str());
3eb78d7e
RR
432
433 return TRUE;
ff7b1510 434}
53b28675 435
debe6624 436bool wxNotebook::SetPageImage( int page, int image )
53b28675 437{
3eb78d7e 438 /* HvdH 28-12-98: now it works, but it's a bit of a kludge */
f861258f 439
3eb78d7e 440 wxNotebookPage* nb_page = GetNotebookPage(page);
ef44a621 441
3eb78d7e 442 if (!nb_page) return FALSE;
f861258f 443
3eb78d7e
RR
444 /* Optimization posibility: return immediately if image unchanged.
445 * Not enabled because it may break existing (stupid) code that
446 * manipulates the imagelist to cycle images */
f861258f 447
3eb78d7e 448 /* if (image == nb_page->m_image) return TRUE; */
f861258f
VZ
449
450 /* For different cases:
3eb78d7e
RR
451 1) no image -> no image
452 2) image -> no image
453 3) no image -> image
454 4) image -> image */
f861258f 455
3eb78d7e
RR
456 if (image == -1 && nb_page->m_image == -1)
457 return TRUE; /* Case 1): Nothing to do. */
f861258f 458
bbe0af5b 459 GtkWidget *pixmapwid = (GtkWidget*) NULL;
f861258f
VZ
460
461 if (nb_page->m_image != -1)
3eb78d7e
RR
462 {
463 /* Case 2) or 4). There is already an image in the gtkhbox. Let's find it */
f861258f 464
3eb78d7e
RR
465 GList *child = gtk_container_children(GTK_CONTAINER(nb_page->m_box));
466 while (child)
467 {
f861258f 468 if (GTK_IS_PIXMAP(child->data))
3eb78d7e
RR
469 {
470 pixmapwid = GTK_WIDGET(child->data);
471 break;
472 }
473 child = child->next;
474 }
f861258f 475
3eb78d7e 476 /* We should have the pixmap widget now */
f861258f
VZ
477 wxASSERT(pixmapwid != NULL);
478
479 if (image == -1)
3eb78d7e
RR
480 {
481 /* If there's no new widget, just remove the old from the box */
482 gtk_container_remove(GTK_CONTAINER(nb_page->m_box), pixmapwid);
483 nb_page->m_image = -1;
53b28675 484
3eb78d7e
RR
485 return TRUE; /* Case 2) */
486 }
487 }
f861258f 488
3eb78d7e
RR
489 /* Only cases 3) and 4) left */
490 wxASSERT( m_imageList != NULL ); /* Just in case */
f861258f 491
3eb78d7e
RR
492 /* Construct the new pixmap */
493 const wxBitmap *bmp = m_imageList->GetBitmap(image);
494 GdkPixmap *pixmap = bmp->GetPixmap();
495 GdkBitmap *mask = (GdkBitmap*) NULL;
f861258f 496 if ( bmp->GetMask() )
3eb78d7e
RR
497 {
498 mask = bmp->GetMask()->GetBitmap();
499 }
f861258f
VZ
500
501 if (pixmapwid == NULL)
3eb78d7e
RR
502 {
503 /* Case 3) No old pixmap. Create a new one and prepend it to the hbox */
504 pixmapwid = gtk_pixmap_new (pixmap, mask );
f861258f 505
3eb78d7e
RR
506 /* CHECKME: Are these pack flags okay? */
507 gtk_box_pack_start(GTK_BOX(nb_page->m_box), pixmapwid, FALSE, FALSE, 3);
508 gtk_widget_show(pixmapwid);
509 }
f861258f 510 else
3eb78d7e
RR
511 {
512 /* Case 4) Simply replace the pixmap */
513 gtk_pixmap_set(GTK_PIXMAP(pixmapwid), pixmap, mask);
514 }
f861258f 515
3eb78d7e 516 nb_page->m_image = image;
53b28675 517
3eb78d7e 518 return TRUE;
ff7b1510 519}
53b28675
RR
520
521void wxNotebook::SetPageSize( const wxSize &WXUNUSED(size) )
522{
b019151f 523 wxFAIL_MSG( _T("wxNotebook::SetPageSize not implemented") );
ff7b1510 524}
53b28675
RR
525
526void wxNotebook::SetPadding( const wxSize &WXUNUSED(padding) )
527{
b019151f 528 wxFAIL_MSG( _T("wxNotebook::SetPadding not implemented") );
ff7b1510 529}
53b28675 530
74e3313b 531void wxNotebook::SetTabSize(const wxSize& WXUNUSED(sz))
ca8b28f2 532{
b019151f 533 wxFAIL_MSG( _T("wxNotebook::SetTabSize not implemented") );
ca8b28f2
JS
534}
535
ff829f3f 536bool wxNotebook::DeleteAllPages()
53b28675 537{
b019151f 538 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") );
a81258be 539
3eb78d7e
RR
540 wxNode *page_node = m_pages.First();
541 while (page_node)
542 {
543 wxNotebookPage *page = (wxNotebookPage*)page_node->Data();
ff829f3f 544
3eb78d7e 545 DeletePage( page->m_id );
ff829f3f 546
3eb78d7e
RR
547 page_node = m_pages.First();
548 }
ff829f3f 549
3eb78d7e 550 return TRUE;
ff7b1510 551}
53b28675 552
ff829f3f 553bool wxNotebook::DeletePage( int page )
53b28675 554{
3eb78d7e
RR
555 wxNotebookPage* nb_page = GetNotebookPage(page);
556 if (!nb_page) return FALSE;
53b28675 557
3eb78d7e
RR
558 int page_num = 0;
559 GList *child = GTK_NOTEBOOK(m_widget)->children;
560 while (child)
561 {
562 if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
563 page_num++;
564 child = child->next;
565 }
53010e52 566
b019151f 567 wxCHECK_MSG( child != NULL, FALSE, _T("illegal notebook index") );
ff829f3f 568
3eb78d7e 569 delete nb_page->m_client;
ff829f3f 570
3eb78d7e 571 m_pages.DeleteObject( nb_page );
fed46e72 572
5549fa65
RR
573 /* adjust the notebook page numbers so that
574 m_id reflects the current position, Daniel Paull */
575 int count = 0;
576 wxNode *node = m_pages.First();
577 wxNotebookPage *pagePtr = (wxNotebookPage *) NULL;
578 while (node)
579 {
580 pagePtr = (wxNotebookPage*)node->Data();
581 pagePtr->m_id = count++;
582 node = node->Next();
583 }
584
3eb78d7e 585 return TRUE;
fed46e72
RR
586}
587
588bool wxNotebook::RemovePage( int page )
589{
3eb78d7e
RR
590 wxNotebookPage* nb_page = GetNotebookPage(page);
591 if (!nb_page) return FALSE;
fed46e72 592
3eb78d7e
RR
593 int page_num = 0;
594 GList *child = GTK_NOTEBOOK(m_widget)->children;
595 while (child)
596 {
597 if (nb_page->m_page == (GtkNotebookPage*)child->data) break;
598 page_num++;
599 child = child->next;
600 }
fed46e72 601
b019151f 602 wxCHECK_MSG( child != NULL, FALSE, _T("illegal notebook index") );
fed46e72 603
3eb78d7e 604 gtk_notebook_remove_page( GTK_NOTEBOOK(m_widget), page_num );
ff829f3f 605
3eb78d7e 606 m_pages.DeleteObject( nb_page );
ff829f3f 607
3eb78d7e 608 return TRUE;
ff7b1510 609}
53b28675 610
ff829f3f 611bool wxNotebook::AddPage(wxWindow* win, const wxString& text,
b292e2f5 612 bool select, int imageId)
53b28675 613{
b019151f 614 wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid notebook") );
a81258be 615
3eb78d7e
RR
616 /* we've created the notebook page in AddChild(). Now we just have to set
617 the caption for the page and set the others parameters. */
8aadf227 618
3eb78d7e 619 wxNotebookPage *page = (wxNotebookPage *) NULL;
53b28675 620
3eb78d7e
RR
621 wxNode *node = m_pages.First();
622 while (node)
623 {
624 page = (wxNotebookPage*)node->Data();
625 if ( page->m_client == win ) break;
626 node = node->Next();
627 }
8aadf227 628
3eb78d7e 629 wxCHECK_MSG( page != NULL, FALSE,
b019151f 630 _T("Can't add a page whose parent is not the notebook!") );
ef44a621 631
3eb78d7e 632 wxCHECK_MSG( page->Add(), FALSE,
b019151f 633 _T("Can't add the same page twice to a notebook.") );
ff829f3f 634
3eb78d7e 635 if (imageId != -1)
e4a81a2e 636 {
3eb78d7e
RR
637 wxASSERT( m_imageList != NULL );
638
639 const wxBitmap *bmp = m_imageList->GetBitmap(imageId);
640 GdkPixmap *pixmap = bmp->GetPixmap();
641 GdkBitmap *mask = (GdkBitmap*) NULL;
642 if ( bmp->GetMask() )
643 {
644 mask = bmp->GetMask()->GetBitmap();
645 }
e4a81a2e 646
3eb78d7e 647 GtkWidget *pixmapwid = gtk_pixmap_new (pixmap, mask );
24d20a8f 648
3eb78d7e 649 gtk_box_pack_start(GTK_BOX(page->m_box), pixmapwid, FALSE, FALSE, 3);
24d20a8f 650
3eb78d7e
RR
651 gtk_widget_show(pixmapwid);
652 }
24d20a8f 653
3eb78d7e
RR
654 /* then set the attributes */
655 page->m_text = text;
b019151f 656 if (page->m_text.IsEmpty()) page->m_text = _T("");
3eb78d7e 657 page->m_image = imageId;
b019151f 658 page->m_label = (GtkLabel *)gtk_label_new(page->m_text.mbc_str());
3eb78d7e 659 gtk_box_pack_end( GTK_BOX(page->m_box), (GtkWidget *)page->m_label, FALSE, FALSE, 3);
741fd203 660
3eb78d7e
RR
661 /* @@@: what does this do? do we still need it?
662 gtk_misc_set_alignment(GTK_MISC(page->m_label), 0.0, 0.5); */
741fd203 663
3eb78d7e 664 gtk_widget_show((GtkWidget *)page->m_label);
741fd203 665
3eb78d7e 666 if (select) SetSelection( GetPageCount()-1 );
ff829f3f 667
3eb78d7e 668 return TRUE;
ff7b1510 669}
53b28675 670
b98d804b
RR
671void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
672{
f861258f 673 if (event.IsWindowChange())
b98d804b 674 AdvanceSelection( event.GetDirection() );
f861258f 675 else
b98d804b
RR
676 event.Skip();
677}
678
ff829f3f 679wxWindow *wxNotebook::GetPage( int page ) const
53b28675 680{
b019151f 681 wxCHECK_MSG( m_widget != NULL, (wxWindow*) NULL, _T("invalid notebook") );
a81258be 682
b292e2f5
RR
683 wxNotebookPage* nb_page = GetNotebookPage(page);
684 if (!nb_page)
685 return (wxWindow *) NULL;
686 else
687 return nb_page->m_client;
ff7b1510 688}
53b28675 689
5a8c929e 690// override these 2 functions to do nothing: everything is done in OnSize
e3e65dac 691void wxNotebook::SetConstraintSizes( bool WXUNUSED(recurse) )
5a8c929e 692{
b292e2f5
RR
693 // don't set the sizes of the pages - their correct size is not yet known
694 wxControl::SetConstraintSizes(FALSE);
5a8c929e
VZ
695}
696
e3e65dac 697bool wxNotebook::DoPhase( int WXUNUSED(nPhase) )
5a8c929e 698{
b292e2f5 699 return TRUE;
5a8c929e
VZ
700}
701
58614078 702void wxNotebook::ApplyWidgetStyle()
a81258be 703{
b292e2f5
RR
704 SetWidgetStyle();
705 gtk_widget_set_style( m_widget, m_widgetStyle );
a81258be
RR
706}
707
58d1c1ae
RR
708bool wxNotebook::IsOwnGtkWindow( GdkWindow *window )
709{
710 return ((m_widget->window == window) ||
711 (GTK_NOTEBOOK(m_widget)->panel == window));
712}
713
53b28675 714//-----------------------------------------------------------------------------
ff829f3f 715// wxNotebookEvent
53b28675
RR
716//-----------------------------------------------------------------------------
717
92976ab6 718IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
5b011451 719