]> git.saurik.com Git - wxWidgets.git/blob - src/gtk/notebook.cpp
use native TAB traversal for GTK+ 2
[wxWidgets.git] / src / gtk / notebook.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/notebook.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Id: $Id$
6 // Copyright: (c) 1998 Robert Roebling, Vadim Zeitlin
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
12
13 #if wxUSE_NOTEBOOK
14
15 #include "wx/notebook.h"
16
17 #ifndef WX_PRECOMP
18 #include "wx/intl.h"
19 #include "wx/log.h"
20 #include "wx/utils.h"
21 #include "wx/msgdlg.h"
22 #include "wx/bitmap.h"
23 #endif
24
25 #include "wx/imaglist.h"
26 #include "wx/fontutil.h"
27
28 #include "wx/gtk/private.h"
29 #include "wx/gtk/win_gtk.h"
30
31 #include <gdk/gdkkeysyms.h>
32
33 // ----------------------------------------------------------------------------
34 // events
35 // ----------------------------------------------------------------------------
36
37 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
38 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
39
40 //-----------------------------------------------------------------------------
41 // data
42 //-----------------------------------------------------------------------------
43
44 extern bool g_blockEventsOnDrag;
45
46 //-----------------------------------------------------------------------------
47 // wxGtkNotebookPage
48 //-----------------------------------------------------------------------------
49
50 // VZ: this is rather ugly as we keep the pages themselves in an array (it
51 // allows us to have quite a few functions implemented in the base class)
52 // but the page data is kept in a separate list, so we must maintain them
53 // in sync manually... of course, the list had been there before the base
54 // class which explains it but it still would be nice to do something
55 // about this one day
56
57 class wxGtkNotebookPage: public wxObject
58 {
59 public:
60 wxGtkNotebookPage()
61 {
62 m_image = -1;
63 m_page = (GtkNotebookPage *) NULL;
64 m_box = (GtkWidget *) NULL;
65 }
66
67 wxString m_text;
68 int m_image;
69 GtkNotebookPage *m_page;
70 GtkLabel *m_label;
71 GtkWidget *m_box; // in which the label and image are packed
72 };
73
74
75 #include "wx/listimpl.cpp"
76 WX_DEFINE_LIST(wxGtkNotebookPagesList)
77
78
79 //-----------------------------------------------------------------------------
80 // "switch_page"
81 //-----------------------------------------------------------------------------
82
83 extern "C" {
84 static void gtk_notebook_page_changing_callback( GtkNotebook *widget,
85 GtkNotebookPage *WXUNUSED(gpage),
86 guint page,
87 wxNotebook *notebook )
88 {
89 int old = gtk_notebook_get_current_page( widget );
90
91 if ( !notebook->SendPageChangingEvent(page) )
92 {
93 // program doesn't allow the page change
94 g_signal_stop_emission_by_name(notebook->m_widget, "switch_page");
95 }
96 else
97 {
98 // the page change event also reports the old page
99 notebook->m_oldSelection = old;
100 }
101 }
102 }
103
104 extern "C" {
105 static void gtk_notebook_page_changed_callback( GtkNotebook *widget,
106 GtkNotebookPage *WXUNUSED(gpage),
107 guint page,
108 wxNotebook *notebook )
109 {
110 int old = notebook->m_oldSelection;
111 notebook->SendPageChangedEvent( old );
112 }
113 }
114
115 //-----------------------------------------------------------------------------
116 // "size_allocate"
117 //-----------------------------------------------------------------------------
118
119 extern "C" {
120 static void gtk_page_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxWindow *win )
121 {
122 if (g_isIdle)
123 wxapp_install_idle_handler();
124
125 if ((win->m_x == alloc->x) &&
126 (win->m_y == alloc->y) &&
127 (win->m_width == alloc->width) &&
128 (win->m_height == alloc->height))
129 {
130 return;
131 }
132
133 win->SetSize( alloc->x, alloc->y, alloc->width, alloc->height );
134
135 /* GTK 1.2 up to version 1.2.5 is broken so that we have to call allocate
136 here in order to make repositioning after resizing to take effect. */
137 if ((gtk_major_version == 1) &&
138 (gtk_minor_version == 2) &&
139 (gtk_micro_version < 6) &&
140 (win->m_wxwindow) &&
141 (GTK_WIDGET_REALIZED(win->m_wxwindow)))
142 {
143 gtk_widget_size_allocate( win->m_wxwindow, alloc );
144 }
145 }
146 }
147
148 //-----------------------------------------------------------------------------
149 // "realize" from m_widget
150 //-----------------------------------------------------------------------------
151
152 extern "C" {
153 static void
154 gtk_notebook_realized_callback( GtkWidget * WXUNUSED(widget), wxWindow *win )
155 {
156 if (g_isIdle)
157 wxapp_install_idle_handler();
158
159 /* GTK 1.2 up to version 1.2.5 is broken so that we have to call a queue_resize
160 here in order to make repositioning before showing to take effect. */
161 gtk_widget_queue_resize( win->m_widget );
162 }
163 }
164
165 //-----------------------------------------------------------------------------
166 // InsertChild callback for wxNotebook
167 //-----------------------------------------------------------------------------
168
169 static void wxInsertChildInNotebook( wxNotebook* parent, wxWindow* child )
170 {
171 // Hack Alert! (Part I): This sets the notebook as the parent of the child
172 // widget, and takes care of some details such as updating the state and
173 // style of the child to reflect its new location. We do this early
174 // because without it GetBestSize (which is used to set the initial size
175 // of controls if an explicit size is not given) will often report
176 // incorrect sizes since the widget's style context is not fully known.
177 // See bug #901694 for details
178 // (http://sourceforge.net/tracker/?func=detail&aid=901694&group_id=9863&atid=109863)
179 gtk_widget_set_parent(child->m_widget, parent->m_widget);
180
181 // NOTE: This should be considered a temporary workaround until we can
182 // work out the details and implement delaying the setting of the initial
183 // size of widgets until the size is really needed.
184 }
185
186 //-----------------------------------------------------------------------------
187 // wxNotebook
188 //-----------------------------------------------------------------------------
189
190 IMPLEMENT_DYNAMIC_CLASS(wxNotebook,wxControl)
191
192 BEGIN_EVENT_TABLE(wxNotebook, wxControl)
193 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
194 END_EVENT_TABLE()
195
196 void wxNotebook::Init()
197 {
198 m_padding = 0;
199
200 m_imageList = (wxImageList *) NULL;
201 m_oldSelection = -1;
202 m_themeEnabled = true;
203 }
204
205 wxNotebook::wxNotebook()
206 {
207 Init();
208 }
209
210 wxNotebook::wxNotebook( wxWindow *parent, wxWindowID id,
211 const wxPoint& pos, const wxSize& size,
212 long style, const wxString& name )
213 {
214 Init();
215 Create( parent, id, pos, size, style, name );
216 }
217
218 wxNotebook::~wxNotebook()
219 {
220 DeleteAllPages();
221 }
222
223 bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
224 const wxPoint& pos, const wxSize& size,
225 long style, const wxString& name )
226 {
227 m_needParent = true;
228 m_insertCallback = (wxInsertChildFunction)wxInsertChildInNotebook;
229
230 if ( (style & wxBK_ALIGN_MASK) == wxBK_DEFAULT )
231 style |= wxBK_TOP;
232
233 if (!PreCreation( parent, pos, size ) ||
234 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
235 {
236 wxFAIL_MSG( wxT("wxNoteBook creation failed") );
237 return false;
238 }
239
240
241 m_widget = gtk_notebook_new();
242
243 gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
244
245 g_signal_connect (m_widget, "switch_page",
246 G_CALLBACK (gtk_notebook_page_changing_callback), this);
247
248 g_signal_connect_after (m_widget, "switch_page",
249 G_CALLBACK (gtk_notebook_page_changed_callback), this);
250
251 m_parent->DoAddChild( this );
252
253 if (m_windowStyle & wxBK_RIGHT)
254 gtk_notebook_set_tab_pos( GTK_NOTEBOOK(m_widget), GTK_POS_RIGHT );
255 if (m_windowStyle & wxBK_LEFT)
256 gtk_notebook_set_tab_pos( GTK_NOTEBOOK(m_widget), GTK_POS_LEFT );
257 if (m_windowStyle & wxBK_BOTTOM)
258 gtk_notebook_set_tab_pos( GTK_NOTEBOOK(m_widget), GTK_POS_BOTTOM );
259
260 PostCreation(size);
261
262 g_signal_connect (m_widget, "realize",
263 G_CALLBACK (gtk_notebook_realized_callback), this);
264
265 return true;
266 }
267
268 int wxNotebook::GetSelection() const
269 {
270 wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid notebook") );
271
272 return gtk_notebook_get_current_page( GTK_NOTEBOOK(m_widget) );
273 }
274
275 wxString wxNotebook::GetPageText( size_t page ) const
276 {
277 wxCHECK_MSG( m_widget != NULL, wxEmptyString, wxT("invalid notebook") );
278
279 wxGtkNotebookPage* nb_page = GetNotebookPage(page);
280 if (nb_page)
281 return nb_page->m_text;
282 else
283 return wxEmptyString;
284 }
285
286 int wxNotebook::GetPageImage( size_t page ) const
287 {
288 wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid notebook") );
289
290 wxGtkNotebookPage* nb_page = GetNotebookPage(page);
291 if (nb_page)
292 return nb_page->m_image;
293 else
294 return -1;
295 }
296
297 wxGtkNotebookPage* wxNotebook::GetNotebookPage( int page ) const
298 {
299 wxCHECK_MSG( m_widget != NULL, (wxGtkNotebookPage*) NULL, wxT("invalid notebook") );
300
301 wxCHECK_MSG( page < (int)m_pagesData.GetCount(), (wxGtkNotebookPage*) NULL, wxT("invalid notebook index") );
302
303 return m_pagesData.Item(page)->GetData();
304 }
305
306 int wxNotebook::DoSetSelection( size_t page, int flags )
307 {
308 wxCHECK_MSG( m_widget != NULL, -1, wxT("invalid notebook") );
309
310 wxCHECK_MSG( page < m_pagesData.GetCount(), -1, wxT("invalid notebook index") );
311
312 int selOld = GetSelection();
313
314 if ( !(flags & SetSelection_SendEvent) )
315 {
316 g_signal_handlers_disconnect_by_func (m_widget,
317 (gpointer) gtk_notebook_page_changing_callback,
318 this);
319
320 g_signal_handlers_disconnect_by_func (m_widget,
321 (gpointer) gtk_notebook_page_changed_callback,
322 this);
323 }
324
325 gtk_notebook_set_current_page( GTK_NOTEBOOK(m_widget), page );
326
327 if ( !(flags & SetSelection_SendEvent) )
328 {
329 // reconnect to signals
330
331 g_signal_connect (m_widget, "switch_page",
332 G_CALLBACK (gtk_notebook_page_changing_callback), this);
333
334 g_signal_connect_after (m_widget, "switch_page",
335 G_CALLBACK (gtk_notebook_page_changed_callback), this);
336 }
337
338 wxNotebookPage *client = GetPage(page);
339 if ( client )
340 client->SetFocus();
341
342 return selOld;
343 }
344
345 bool wxNotebook::SetPageText( size_t page, const wxString &text )
346 {
347 wxCHECK_MSG( m_widget != NULL, false, wxT("invalid notebook") );
348
349 wxGtkNotebookPage* nb_page = GetNotebookPage(page);
350
351 wxCHECK_MSG( nb_page, false, wxT("SetPageText: invalid page index") );
352
353 nb_page->m_text = text;
354
355 gtk_label_set_text( nb_page->m_label, wxGTK_CONV( nb_page->m_text ) );
356
357 return true;
358 }
359
360 bool wxNotebook::SetPageImage( size_t page, int image )
361 {
362 /* HvdH 28-12-98: now it works, but it's a bit of a kludge */
363
364 wxGtkNotebookPage* nb_page = GetNotebookPage(page);
365
366 if (!nb_page) return false;
367
368 /* Optimization posibility: return immediately if image unchanged.
369 * Not enabled because it may break existing (stupid) code that
370 * manipulates the imagelist to cycle images */
371
372 /* if (image == nb_page->m_image) return true; */
373
374 /* For different cases:
375 1) no image -> no image
376 2) image -> no image
377 3) no image -> image
378 4) image -> image */
379
380 if (image == -1 && nb_page->m_image == -1)
381 return true; /* Case 1): Nothing to do. */
382
383 GtkWidget *pixmapwid = (GtkWidget*) NULL;
384
385 if (nb_page->m_image != -1)
386 {
387 /* Case 2) or 4). There is already an image in the gtkhbox. Let's find it */
388
389 GList *child = gtk_container_get_children(GTK_CONTAINER(nb_page->m_box));
390 while (child)
391 {
392 if (GTK_IS_IMAGE(child->data))
393 {
394 pixmapwid = GTK_WIDGET(child->data);
395 break;
396 }
397 child = child->next;
398 }
399
400 /* We should have the pixmap widget now */
401 wxASSERT(pixmapwid != NULL);
402
403 if (image == -1)
404 {
405 /* If there's no new widget, just remove the old from the box */
406 gtk_container_remove(GTK_CONTAINER(nb_page->m_box), pixmapwid);
407 nb_page->m_image = -1;
408
409 return true; /* Case 2) */
410 }
411 }
412
413 /* Only cases 3) and 4) left */
414 wxASSERT( m_imageList != NULL ); /* Just in case */
415
416 /* Construct the new pixmap */
417 const wxBitmap *bmp = m_imageList->GetBitmapPtr(image);
418
419 if (pixmapwid == NULL)
420 {
421 /* Case 3) No old pixmap. Create a new one and prepend it to the hbox */
422 pixmapwid = gtk_image_new_from_pixbuf(bmp->GetPixbuf());
423
424 /* CHECKME: Are these pack flags okay? */
425 gtk_box_pack_start(GTK_BOX(nb_page->m_box), pixmapwid, FALSE, FALSE, m_padding);
426 gtk_widget_show(pixmapwid);
427 }
428 else
429 {
430 /* Case 4) Simply replace the pixmap */
431 gtk_image_set_from_pixbuf((GtkImage*)pixmapwid, bmp->GetPixbuf());
432 }
433
434 nb_page->m_image = image;
435
436 return true;
437 }
438
439 void wxNotebook::SetPageSize( const wxSize &WXUNUSED(size) )
440 {
441 wxFAIL_MSG( wxT("wxNotebook::SetPageSize not implemented") );
442 }
443
444 void wxNotebook::SetPadding( const wxSize &padding )
445 {
446 wxCHECK_RET( m_widget != NULL, wxT("invalid notebook") );
447
448 m_padding = padding.GetWidth();
449
450 int i;
451 for (i=0; i<int(GetPageCount()); i++)
452 {
453 wxGtkNotebookPage* nb_page = GetNotebookPage(i);
454 wxASSERT(nb_page != NULL);
455
456 if (nb_page->m_image != -1)
457 {
458 // gtk_box_set_child_packing sets padding on BOTH sides
459 // icon provides left padding, label provides center and right
460 int image = nb_page->m_image;
461 SetPageImage(i,-1);
462 SetPageImage(i,image);
463 }
464 wxASSERT(nb_page->m_label);
465 gtk_box_set_child_packing(GTK_BOX(nb_page->m_box),
466 GTK_WIDGET(nb_page->m_label),
467 FALSE, FALSE, m_padding, GTK_PACK_END);
468 }
469 }
470
471 void wxNotebook::SetTabSize(const wxSize& WXUNUSED(sz))
472 {
473 wxFAIL_MSG( wxT("wxNotebook::SetTabSize not implemented") );
474 }
475
476 bool wxNotebook::DeleteAllPages()
477 {
478 wxCHECK_MSG( m_widget != NULL, false, wxT("invalid notebook") );
479
480 while (m_pagesData.GetCount() > 0)
481 DeletePage( m_pagesData.GetCount()-1 );
482
483 wxASSERT_MSG( GetPageCount() == 0, _T("all pages must have been deleted") );
484
485 InvalidateBestSize();
486 return wxNotebookBase::DeleteAllPages();
487 }
488
489 wxNotebookPage *wxNotebook::DoRemovePage( size_t page )
490 {
491 wxNotebookPage *client = wxNotebookBase::DoRemovePage(page);
492 if ( !client )
493 return NULL;
494
495 gtk_widget_ref( client->m_widget );
496 gtk_widget_unrealize( client->m_widget );
497
498 // we don't need to unparent the client->m_widget; GTK+ will do
499 // that for us (and will throw a warning if we do it!)
500
501 gtk_notebook_remove_page( GTK_NOTEBOOK(m_widget), page );
502
503 wxGtkNotebookPage* p = GetNotebookPage(page);
504 m_pagesData.DeleteObject(p);
505 delete p;
506
507 return client;
508 }
509
510 bool wxNotebook::InsertPage( size_t position,
511 wxNotebookPage* win,
512 const wxString& text,
513 bool select,
514 int imageId )
515 {
516 wxCHECK_MSG( m_widget != NULL, false, wxT("invalid notebook") );
517
518 wxCHECK_MSG( win->GetParent() == this, false,
519 wxT("Can't add a page whose parent is not the notebook!") );
520
521 wxCHECK_MSG( position <= GetPageCount(), false,
522 _T("invalid page index in wxNotebookPage::InsertPage()") );
523
524 // Hack Alert! (Part II): See above in wxInsertChildInNotebook callback
525 // why this has to be done. NOTE: using gtk_widget_unparent here does not
526 // work as it seems to undo too much and will cause errors in the
527 // gtk_notebook_insert_page below, so instead just clear the parent by
528 // hand here.
529 win->m_widget->parent = NULL;
530
531 if (m_themeEnabled)
532 win->SetThemeEnabled(true);
533
534 GtkNotebook *notebook = GTK_NOTEBOOK(m_widget);
535
536 wxGtkNotebookPage *nb_page = new wxGtkNotebookPage();
537
538 if ( position == GetPageCount() )
539 m_pagesData.Append( nb_page );
540 else
541 m_pagesData.Insert( position, nb_page );
542
543 m_pages.Insert(win, position);
544
545 nb_page->m_box = gtk_hbox_new( FALSE, 1 );
546 gtk_container_set_border_width((GtkContainer*)nb_page->m_box, 2);
547
548 g_signal_connect (win->m_widget, "size_allocate",
549 G_CALLBACK (gtk_page_size_callback), win);
550
551 gtk_notebook_insert_page( notebook, win->m_widget, nb_page->m_box, position );
552
553 nb_page->m_page = (GtkNotebookPage*) g_list_last(notebook->children)->data;
554
555 /* set the label image */
556 nb_page->m_image = imageId;
557
558 if (imageId != -1)
559 {
560 wxASSERT( m_imageList != NULL );
561
562 const wxBitmap *bmp = m_imageList->GetBitmapPtr(imageId);
563 GtkWidget* pixmapwid = gtk_image_new_from_pixbuf(bmp->GetPixbuf());
564 gtk_box_pack_start(GTK_BOX(nb_page->m_box), pixmapwid, FALSE, FALSE, m_padding);
565 gtk_widget_show(pixmapwid);
566 }
567
568 /* set the label text */
569
570 nb_page->m_text = wxStripMenuCodes(text);
571 if (nb_page->m_text.empty()) nb_page->m_text = wxEmptyString;
572
573 nb_page->m_label = GTK_LABEL( gtk_label_new(wxGTK_CONV(nb_page->m_text)) );
574 gtk_box_pack_end( GTK_BOX(nb_page->m_box), GTK_WIDGET(nb_page->m_label), FALSE, FALSE, m_padding );
575
576 /* apply current style */
577 GtkRcStyle *style = CreateWidgetStyle();
578 if ( style )
579 {
580 gtk_widget_modify_style(GTK_WIDGET(nb_page->m_label), style);
581 gtk_rc_style_unref(style);
582 }
583
584 /* show the label */
585 gtk_widget_show( GTK_WIDGET(nb_page->m_label) );
586
587 if (select && (m_pagesData.GetCount() > 1))
588 {
589 SetSelection( position );
590 }
591
592 InvalidateBestSize();
593 return true;
594 }
595
596 // helper for HitTest(): check if the point lies inside the given widget which
597 // is the child of the notebook whose position and border size are passed as
598 // parameters
599 static bool
600 IsPointInsideWidget(const wxPoint& pt, GtkWidget *w,
601 gint x, gint y, gint border = 0)
602 {
603 return
604 (pt.x >= w->allocation.x - x - border) &&
605 (pt.x <= w->allocation.x - x + border + w->allocation.width) &&
606 (pt.y >= w->allocation.y - y - border) &&
607 (pt.y <= w->allocation.y - y + border + w->allocation.height);
608 }
609
610 int wxNotebook::HitTest(const wxPoint& pt, long *flags) const
611 {
612 const gint x = m_widget->allocation.x;
613 const gint y = m_widget->allocation.y;
614
615 const size_t count = GetPageCount();
616 size_t i = 0;
617
618 GtkNotebook * notebook = GTK_NOTEBOOK(m_widget);
619 if (gtk_notebook_get_scrollable(notebook))
620 i = g_list_position( notebook->children, notebook->first_tab );
621
622 for ( ; i < count; i++ )
623 {
624 wxGtkNotebookPage* nb_page = GetNotebookPage(i);
625 GtkWidget *box = nb_page->m_box;
626
627 const gint border = gtk_container_get_border_width(GTK_CONTAINER(box));
628
629 if ( IsPointInsideWidget(pt, box, x, y, border) )
630 {
631 // ok, we're inside this tab -- now find out where, if needed
632 if ( flags )
633 {
634 GtkWidget *pixmap = NULL;
635
636 GList *children = gtk_container_get_children(GTK_CONTAINER(box));
637 for ( GList *child = children; child; child = child->next )
638 {
639 if (GTK_IS_IMAGE(child->data))
640 {
641 pixmap = GTK_WIDGET(child->data);
642 break;
643 }
644 }
645
646 if ( children )
647 g_list_free(children);
648
649 if ( pixmap && IsPointInsideWidget(pt, pixmap, x, y) )
650 {
651 *flags = wxBK_HITTEST_ONICON;
652 }
653 else if ( IsPointInsideWidget(pt, GTK_WIDGET(nb_page->m_label), x, y) )
654 {
655 *flags = wxBK_HITTEST_ONLABEL;
656 }
657 else
658 {
659 *flags = wxBK_HITTEST_ONITEM;
660 }
661 }
662
663 return i;
664 }
665 }
666
667 if ( flags )
668 {
669 *flags = wxBK_HITTEST_NOWHERE;
670 wxWindowBase * page = GetCurrentPage();
671 if ( page )
672 {
673 // rect origin is in notebook's parent coordinates
674 wxRect rect = page->GetRect();
675
676 // adjust it to the notebook's coordinates
677 wxPoint pos = GetPosition();
678 rect.x -= pos.x;
679 rect.y -= pos.y;
680 if ( rect.Contains( pt ) )
681 *flags |= wxBK_HITTEST_ONPAGE;
682 }
683 }
684
685 return wxNOT_FOUND;
686 }
687
688 void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
689 {
690 if (event.IsWindowChange())
691 AdvanceSelection( event.GetDirection() );
692 else
693 event.Skip();
694 }
695
696 #if wxUSE_CONSTRAINTS
697
698 // override these 2 functions to do nothing: everything is done in OnSize
699 void wxNotebook::SetConstraintSizes( bool WXUNUSED(recurse) )
700 {
701 // don't set the sizes of the pages - their correct size is not yet known
702 wxControl::SetConstraintSizes(false);
703 }
704
705 bool wxNotebook::DoPhase( int WXUNUSED(nPhase) )
706 {
707 return true;
708 }
709
710 #endif
711
712 void wxNotebook::DoApplyWidgetStyle(GtkRcStyle *style)
713 {
714 gtk_widget_modify_style(m_widget, style);
715 size_t cnt = m_pagesData.GetCount();
716 for (size_t i = 0; i < cnt; i++)
717 gtk_widget_modify_style(GTK_WIDGET(GetNotebookPage(i)->m_label), style);
718 }
719
720 GdkWindow *wxNotebook::GTKGetWindow(wxArrayGdkWindows& windows) const
721 {
722 windows.push_back(m_widget->window);
723 windows.push_back(GTK_NOTEBOOK(m_widget)->event_window);
724
725 return NULL;
726 }
727
728 // static
729 wxVisualAttributes
730 wxNotebook::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
731 {
732 return GetDefaultAttributesFromGTKWidget(gtk_notebook_new);
733 }
734
735 //-----------------------------------------------------------------------------
736 // wxNotebookEvent
737 //-----------------------------------------------------------------------------
738
739 IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
740
741 #endif