Corrected wxRTTI for wxNotebook so dynamic casting to wxBookCtrlBase works
[wxWidgets.git] / src / os2 / notebook.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/notebook.cpp
3 // Purpose: implementation of wxNotebook
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/12/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_NOTEBOOK
16
17 #include "wx/notebook.h"
18
19 // wxWidgets
20 #ifndef WX_PRECOMP
21 #include "wx/app.h"
22 #include "wx/dcclient.h"
23 #include "wx/string.h"
24 #include "wx/settings.h"
25 #include "wx/log.h"
26 #include "wx/event.h"
27 #include "wx/control.h"
28 #endif // WX_PRECOMP
29
30 #include "wx/imaglist.h"
31
32 #include "wx/os2/private.h"
33
34 // ----------------------------------------------------------------------------
35 // macros
36 // ----------------------------------------------------------------------------
37
38 // check that the page index is valid
39 #define IS_VALID_PAGE(nPage) ( \
40 /* size_t is _always_ >= 0 */ \
41 /* ((nPage) >= 0) && */ \
42 ((nPage) < GetPageCount()) \
43 )
44
45 // hide the ugly cast
46 #define m_hWnd (HWND)GetHWND()
47
48 // ----------------------------------------------------------------------------
49 // constants
50 // ----------------------------------------------------------------------------
51
52 // ----------------------------------------------------------------------------
53 // event table
54 // ----------------------------------------------------------------------------
55
56 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
57 DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
58
59 BEGIN_EVENT_TABLE(wxNotebook, wxBookCtrlBase)
60 EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, wxNotebook::OnSelChange)
61 EVT_SIZE(wxNotebook::OnSize)
62 EVT_SET_FOCUS(wxNotebook::OnSetFocus)
63 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
64 END_EVENT_TABLE()
65
66 IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxBookCtrlBase)
67 IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxNotifyEvent)
68
69 // ============================================================================
70 // implementation
71 // ============================================================================
72
73 // ----------------------------------------------------------------------------
74 // wxNotebook construction
75 // ----------------------------------------------------------------------------
76
77 //
78 // Common part of all ctors
79 //
80 void wxNotebook::Init()
81 {
82 m_imageList = NULL;
83 m_nSelection = -1;
84 m_nTabSize = 0;
85 } // end of wxNotebook::Init
86
87 //
88 // Default for dynamic class
89 //
90 wxNotebook::wxNotebook()
91 {
92 Init();
93 } // end of wxNotebook::wxNotebook
94
95 //
96 // The same arguments as for wxControl
97 //
98 wxNotebook::wxNotebook(
99 wxWindow* pParent
100 , wxWindowID vId
101 , const wxPoint& rPos
102 , const wxSize& rSize
103 , long lStyle
104 , const wxString& rsName
105 )
106 {
107 Init();
108 Create( pParent
109 ,vId
110 ,rPos
111 ,rSize
112 ,lStyle
113 ,rsName
114 );
115 } // end of wxNotebook::wxNotebook
116
117 //
118 // Create() function
119 //
120 bool wxNotebook::Create( wxWindow* pParent,
121 wxWindowID vId,
122 const wxPoint& rPos,
123 const wxSize& rSize,
124 long lStyle,
125 const wxString& rsName )
126 {
127 if ( (lStyle & wxBK_ALIGN_MASK) == wxBK_DEFAULT )
128 lStyle |= wxBK_TOP;
129 //
130 // Base init
131 //
132 if (!CreateControl( pParent
133 ,vId
134 ,rPos
135 ,rSize
136 ,lStyle
137 ,wxDefaultValidator
138 ,rsName
139 ))
140 return false;
141
142 //
143 // Notebook, so explicitly specify 0 as last parameter
144 //
145 if (!OS2CreateControl( wxT("NOTEBOOK")
146 ,wxEmptyString
147 ,rPos
148 ,rSize
149 ,lStyle | wxTAB_TRAVERSAL
150 ))
151 return false;
152
153 SetBackgroundColour(wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
154 return true;
155 } // end of wxNotebook::Create
156
157 WXDWORD wxNotebook::OS2GetStyle (
158 long lStyle
159 , WXDWORD* pdwExstyle
160 ) const
161 {
162 WXDWORD dwTabStyle = wxControl::OS2GetStyle( lStyle
163 ,pdwExstyle
164 );
165
166 dwTabStyle |= WS_TABSTOP | BKS_SOLIDBIND | BKS_ROUNDEDTABS | BKS_TABTEXTCENTER | BKS_TABBEDDIALOG;
167
168 if (lStyle & wxBK_BOTTOM)
169 dwTabStyle |= BKS_MAJORTABBOTTOM | BKS_BACKPAGESBL;
170 else if (lStyle & wxBK_RIGHT)
171 dwTabStyle |= BKS_MAJORTABRIGHT | BKS_BACKPAGESBR;
172 else if (lStyle & wxBK_LEFT)
173 dwTabStyle |= BKS_MAJORTABLEFT | BKS_BACKPAGESTL;
174 else // default to top
175 dwTabStyle |= BKS_MAJORTABTOP | BKS_BACKPAGESTR;
176
177 //
178 // Ex style
179 //
180 if (pdwExstyle )
181 {
182 //
183 // Note that we never want to have the default WS_EX_CLIENTEDGE style
184 // as it looks too ugly for the notebooks
185 //
186 *pdwExstyle = 0;
187 }
188 return dwTabStyle;
189 } // end of wxNotebook::OS2GetStyle
190
191 // ----------------------------------------------------------------------------
192 // wxNotebook accessors
193 // ----------------------------------------------------------------------------
194
195 size_t wxNotebook::GetPageCount() const
196 {
197 //
198 // Consistency check
199 //
200 wxASSERT((int)m_pages.Count() == (int)::WinSendMsg(GetHWND(), BKM_QUERYPAGECOUNT, (MPARAM)0, (MPARAM)BKA_END));
201 return m_pages.Count();
202 } // end of wxNotebook::GetPageCount
203
204 int wxNotebook::GetRowCount() const
205 {
206 return (int)::WinSendMsg( GetHWND()
207 ,BKM_QUERYPAGECOUNT
208 ,(MPARAM)0
209 ,(MPARAM)BKA_MAJOR
210 );
211 } // end of wxNotebook::GetRowCount
212
213 int wxNotebook::SetSelection( size_t nPage )
214 {
215 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
216
217 if (nPage != (size_t)m_nSelection)
218 {
219 wxNotebookEvent vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING
220 ,m_windowId
221 );
222
223 vEvent.SetSelection(nPage);
224 vEvent.SetOldSelection(m_nSelection);
225 vEvent.SetEventObject(this);
226 if (!HandleWindowEvent(vEvent) || vEvent.IsAllowed())
227 {
228
229 //
230 // Program allows the page change
231 //
232 vEvent.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
233 HandleWindowEvent(vEvent);
234
235 ::WinSendMsg( GetHWND()
236 ,BKM_TURNTOPAGE
237 ,MPFROMLONG((ULONG)m_alPageId[nPage])
238 ,(MPARAM)0
239 );
240 }
241 }
242 m_nSelection = nPage;
243 return nPage;
244 } // end of wxNotebook::SetSelection
245
246 int wxNotebook::ChangeSelection( size_t nPage )
247 {
248 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
249
250 if (nPage != (size_t)m_nSelection)
251 {
252 ::WinSendMsg( GetHWND()
253 ,BKM_TURNTOPAGE
254 ,MPFROMLONG((ULONG)m_alPageId[nPage])
255 ,(MPARAM)0
256 );
257 }
258 m_nSelection = nPage;
259 return nPage;
260 }
261
262 bool wxNotebook::SetPageText( size_t nPage,
263 const wxString& rsStrText )
264 {
265 wxCHECK_MSG( IS_VALID_PAGE(nPage), false, wxT("notebook page out of range") );
266 return (bool)::WinSendMsg( m_hWnd
267 ,BKM_SETTABTEXT
268 ,MPFROMLONG((ULONG)m_alPageId[nPage])
269 ,MPFROMP((const char*)rsStrText.c_str())
270 );
271 } // end of wxNotebook::SetPageText
272
273 wxString wxNotebook::GetPageText ( size_t nPage ) const
274 {
275 BOOKTEXT vBookText;
276 wxChar zBuf[256];
277 wxString sStr;
278 ULONG ulRc;
279
280 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxEmptyString, wxT("notebook page out of range") );
281
282 memset(&vBookText, '\0', sizeof(BOOKTEXT));
283 vBookText.textLen = 0; // This will get the length
284 ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
285 ,BKM_QUERYTABTEXT
286 ,MPFROMLONG((ULONG)m_alPageId[nPage])
287 ,MPFROMP(&vBookText)
288 ));
289 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
290 {
291 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS)
292 {
293 wxLogError(wxT("Invalid Page Id for page text querry."));
294 }
295 return wxEmptyString;
296 }
297 vBookText.textLen = ulRc + 1; // To get the null terminator
298 vBookText.pString = (char*)zBuf;
299
300 //
301 // Now get the actual text
302 //
303 ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
304 ,BKM_QUERYTABTEXT
305 ,MPFROMLONG((ULONG)m_alPageId[nPage])
306 ,MPFROMP(&vBookText)
307 ));
308 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
309 {
310 return wxEmptyString;
311 }
312 if (ulRc > 255L)
313 ulRc = 255L;
314
315 vBookText.pString[ulRc] = '\0';
316 sStr = (wxChar*)vBookText.pString;
317 return sStr;
318 } // end of wxNotebook::GetPageText
319
320 int wxNotebook::GetPageImage ( size_t nPage ) const
321 {
322 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
323
324 //
325 // For OS/2 just return the page
326 //
327 return nPage;
328 } // end of wxNotebook::GetPageImage
329
330 bool wxNotebook::SetPageImage (
331 size_t nPage
332 , int nImage
333 )
334 {
335 wxBitmap vBitmap = (wxBitmap)m_imageList->GetBitmap(nImage);
336
337 return (bool)::WinSendMsg( GetHWND()
338 ,BKM_SETTABBITMAP
339 ,MPFROMLONG((ULONG)m_alPageId[nPage])
340 ,(MPARAM)wxCopyBmp(vBitmap.GetHBITMAP(), true)
341 );
342 } // end of wxNotebook::SetPageImage
343
344 void wxNotebook::SetImageList (
345 wxImageList* pImageList
346 )
347 {
348 //
349 // Does not really do anything yet, but at least we need to
350 // update the base class.
351 //
352 wxNotebookBase::SetImageList(pImageList);
353 } // end of wxNotebook::SetImageList
354
355 // ----------------------------------------------------------------------------
356 // wxNotebook size settings
357 // ----------------------------------------------------------------------------
358 void wxNotebook::SetPageSize (
359 const wxSize& rSize
360 )
361 {
362 SetSize(rSize);
363 } // end of wxNotebook::SetPageSize
364
365 void wxNotebook::SetPadding (
366 const wxSize& WXUNUSED(rPadding)
367 )
368 {
369 //
370 // No padding in OS/2
371 //
372 } // end of wxNotebook::SetPadding
373
374 void wxNotebook::SetTabSize (
375 const wxSize& rSize
376 )
377 {
378 ::WinSendMsg( GetHWND()
379 ,BKM_SETDIMENSIONS
380 ,MPFROM2SHORT( (USHORT)rSize.x
381 ,(USHORT)rSize.y
382 )
383 ,(MPARAM)BKA_MAJORTAB
384 );
385 } // end of wxNotebook::SetTabSize
386
387 // ----------------------------------------------------------------------------
388 // wxNotebook operations
389 // ----------------------------------------------------------------------------
390
391 //
392 // Remove one page from the notebook, without deleting
393 //
394 wxNotebookPage* wxNotebook::DoRemovePage ( size_t nPage )
395 {
396 wxNotebookPage* pPageRemoved = wxNotebookBase::DoRemovePage(nPage);
397
398 if (!pPageRemoved)
399 return NULL;
400
401 ::WinSendMsg( GetHWND()
402 ,BKM_DELETEPAGE
403 ,MPFROMLONG((ULONG)m_alPageId[nPage])
404 ,(MPARAM)BKA_TAB
405 );
406 if (m_pages.IsEmpty())
407 {
408 //
409 // No selection any more, the notebook becamse empty
410 //
411 m_nSelection = -1;
412 }
413 else // notebook still not empty
414 {
415 //
416 // Change the selected page if it was deleted or became invalid
417 //
418 int nSelNew;
419
420 if (m_nSelection == (int)GetPageCount())
421 {
422 //
423 // Last page deleted, make the new last page the new selection
424 //
425 nSelNew = m_nSelection - 1;
426 }
427 else if (nPage <= (size_t)m_nSelection)
428 {
429 //
430 // We must show another page, even if it has the same index
431 //
432 nSelNew = m_nSelection;
433 }
434 else // nothing changes for the currently selected page
435 {
436 nSelNew = -1;
437
438 //
439 // We still must refresh the current page: this needs to be done
440 // for some unknown reason if the tab control shows the up-down
441 // control (i.e. when there are too many pages) -- otherwise after
442 // deleting a page nothing at all is shown
443 //
444 m_pages[m_nSelection]->Refresh();
445 }
446
447 if (nSelNew != -1)
448 {
449 //
450 // m_nSelection must be always valid so reset it before calling
451 // SetSelection()
452 //
453 m_nSelection = -1;
454 SetSelection(nSelNew);
455 }
456 }
457 return pPageRemoved;
458 } // end of wxNotebook::DoRemovePage
459
460 //
461 // Remove all pages
462 //
463 bool wxNotebook::DeleteAllPages()
464 {
465 int nPageCount = GetPageCount();
466 int nPage;
467
468 for (nPage = 0; nPage < nPageCount; nPage++)
469 delete m_pages[nPage];
470 m_pages.Clear();
471 ::WinSendMsg( GetHWND()
472 ,BKM_DELETEPAGE
473 ,(MPARAM)0
474 ,(MPARAM)BKA_ALL
475 );
476 m_nSelection = -1;
477
478 return true;
479 } // end of wxNotebook::DeleteAllPages
480
481 //
482 // Add a page to the notebook
483 //
484 bool wxNotebook::AddPage (
485 wxNotebookPage* pPage
486 , const wxString& rStrText
487 , bool bSelect
488 , int nImageId
489 )
490 {
491 return InsertPage( GetPageCount()
492 ,pPage
493 ,rStrText
494 ,bSelect
495 ,nImageId
496 );
497 } // end of wxNotebook::AddPage
498
499 //
500 // Same as AddPage() but does it at given position
501 //
502 bool wxNotebook::InsertPage ( size_t nPage,
503 wxNotebookPage* pPage,
504 const wxString& rsStrText,
505 bool bSelect,
506 int nImageId )
507 {
508 ULONG ulApiPage;
509
510 wxASSERT( pPage != NULL );
511 wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), false );
512
513 //
514 // Under OS/2 we can only insert FIRST, LAST, NEXT or PREV. Requires
515 // two different calls to the API. Page 1 uses the BKA_FIRST. Subsequent
516 // pages use the previous page ID coupled with a BKA_NEXT call. Unlike
517 // Windows, OS/2 uses an internal Page ID to ID the pages.
518 //
519 // OS/2 also has a nice auto-size feature that automatically sizes the
520 // the attached window so we don't have to worry about the size of the
521 // window on the page.
522 //
523 if (nPage == 0)
524 {
525 ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
526 ,BKM_INSERTPAGE
527 ,(MPARAM)0
528 ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_FIRST)
529 ));
530 if (ulApiPage == 0L)
531 {
532 ERRORID vError;
533 wxString sError;
534
535 vError = ::WinGetLastError(vHabmain);
536 sError = wxPMErrorToStr(vError);
537 return false;
538 }
539 m_alPageId.Insert((long)ulApiPage, nPage);
540 }
541 else
542 {
543 ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
544 ,BKM_INSERTPAGE
545 ,MPFROMLONG((ULONG)m_alPageId[nPage - 1])
546 ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_NEXT)
547 ));
548 if (ulApiPage == 0L)
549 {
550 ERRORID vError;
551 wxString sError;
552
553 vError = ::WinGetLastError(vHabmain);
554 sError = wxPMErrorToStr(vError);
555 return false;
556 }
557 m_alPageId.Insert((long)ulApiPage, nPage);
558 }
559
560 //
561 // Associate a window handle with the page
562 //
563 if (pPage)
564 {
565 if (!::WinSendMsg( GetHWND()
566 ,BKM_SETPAGEWINDOWHWND
567 ,MPFROMLONG((ULONG)m_alPageId[nPage])
568 ,MPFROMHWND(pPage->GetHWND())
569 ))
570 return false;
571 }
572 //
573 // If the inserted page is before the selected one, we must update the
574 // index of the selected page
575 //
576 if (nPage <= (size_t)m_nSelection)
577 {
578 //
579 // One extra page added
580 //
581 m_nSelection++;
582 }
583
584 if (pPage)
585 {
586 //
587 // Save the pointer to the page
588 //
589 m_pages.Insert( pPage
590 ,nPage
591 );
592 }
593
594 //
595 // Now set TAB dimenstions
596 //
597
598 wxWindowDC vDC(this);
599 wxCoord nTextX;
600 wxCoord nTextY;
601
602 vDC.GetTextExtent(rsStrText, &nTextX, &nTextY);
603 nTextY *= 2;
604 nTextX = (wxCoord)(nTextX * 1.3);
605 if (nTextX > m_nTabSize)
606 {
607 m_nTabSize = nTextX;
608 ::WinSendMsg( GetHWND()
609 ,BKM_SETDIMENSIONS
610 ,MPFROM2SHORT((USHORT)m_nTabSize, (USHORT)nTextY)
611 ,(MPARAM)BKA_MAJORTAB
612 );
613 }
614 //
615 // Now set any TAB text
616 //
617 if (!rsStrText.empty())
618 {
619 if (!SetPageText( nPage
620 ,rsStrText
621 ))
622 return false;
623 }
624
625 //
626 // Now set any TAB bitmap image
627 //
628 if (nImageId != -1)
629 {
630 if (!SetPageImage( nPage
631 ,nImageId
632 ))
633 return false;
634 }
635
636 if (pPage)
637 {
638 //
639 // Don't show pages by default (we'll need to adjust their size first)
640 //
641 HWND hWnd = GetWinHwnd(pPage);
642
643 WinSetWindowULong( hWnd
644 ,QWL_STYLE
645 ,WinQueryWindowULong( hWnd
646 ,QWL_STYLE
647 ) & ~WS_VISIBLE
648 );
649
650 //
651 // This updates internal flag too - otherwise it will get out of sync
652 //
653 pPage->Show(false);
654 }
655
656 //
657 // Some page should be selected: either this one or the first one if there is
658 // still no selection
659 //
660 int nSelNew = -1;
661
662 if (bSelect)
663 nSelNew = nPage;
664 else if ( m_nSelection == -1 )
665 nSelNew = 0;
666
667 if (nSelNew != -1)
668 SetSelection(nSelNew);
669
670 InvalidateBestSize();
671
672 return true;
673 } // end of wxNotebook::InsertPage
674
675 // ----------------------------------------------------------------------------
676 // wxNotebook callbacks
677 // ----------------------------------------------------------------------------
678 void wxNotebook::OnSize(
679 wxSizeEvent& rEvent
680 )
681 {
682 rEvent.Skip();
683 } // end of wxNotebook::OnSize
684
685 void wxNotebook::OnSelChange (
686 wxNotebookEvent& rEvent
687 )
688 {
689 //
690 // Is it our tab control?
691 //
692 if (rEvent.GetEventObject() == this)
693 {
694 int nPageCount = GetPageCount();
695 int nSel;
696 ULONG ulOS2Sel = (ULONG)rEvent.GetOldSelection();
697 bool bFound = false;
698
699 for (nSel = 0; nSel < nPageCount; nSel++)
700 {
701 if (ulOS2Sel == (ULONG)m_alPageId[nSel])
702 {
703 bFound = true;
704 break;
705 }
706 }
707
708 if (!bFound)
709 return;
710
711 m_pages[nSel]->Show(false);
712
713 ulOS2Sel = (ULONG)rEvent.GetSelection();
714
715 bFound = false;
716
717 for (nSel = 0; nSel < nPageCount; nSel++)
718 {
719 if (ulOS2Sel == (ULONG)m_alPageId[nSel])
720 {
721 bFound = true;
722 break;
723 }
724 }
725
726 if (!bFound)
727 return;
728
729 wxNotebookPage* pPage = m_pages[nSel];
730
731 pPage->Show(true);
732 m_nSelection = nSel;
733 }
734
735 //
736 // We want to give others a chance to process this message as well
737 //
738 rEvent.Skip();
739 } // end of wxNotebook::OnSelChange
740
741 void wxNotebook::OnSetFocus (
742 wxFocusEvent& rEvent
743 )
744 {
745 //
746 // This function is only called when the focus is explicitly set (i.e. from
747 // the program) to the notebook - in this case we don't need the
748 // complicated OnNavigationKey() logic because the programmer knows better
749 // what [s]he wants
750 //
751 // set focus to the currently selected page if any
752 //
753 if (m_nSelection != -1)
754 m_pages[m_nSelection]->SetFocus();
755 rEvent.Skip();
756 } // end of wxNotebook::OnSetFocus
757
758 void wxNotebook::OnNavigationKey (
759 wxNavigationKeyEvent& rEvent
760 )
761 {
762 if (rEvent.IsWindowChange())
763 {
764 //
765 // Change pages
766 //
767 AdvanceSelection(rEvent.GetDirection());
768 }
769 else
770 {
771 //
772 // We get this event in 2 cases
773 //
774 // a) one of our pages might have generated it because the user TABbed
775 // out from it in which case we should propagate the event upwards and
776 // our parent will take care of setting the focus to prev/next sibling
777 //
778 // or
779 //
780 // b) the parent panel wants to give the focus to us so that we
781 // forward it to our selected page. We can't deal with this in
782 // OnSetFocus() because we don't know which direction the focus came
783 // from in this case and so can't choose between setting the focus to
784 // first or last panel child
785 //
786 wxWindow* pParent = GetParent();
787
788 if (rEvent.GetEventObject() == pParent)
789 {
790 //
791 // No, it doesn't come from child, case (b): forward to a page
792 //
793 if (m_nSelection != -1)
794 {
795 //
796 // So that the page knows that the event comes from it's parent
797 // and is being propagated downwards
798 //
799 rEvent.SetEventObject(this);
800
801 wxWindow* pPage = m_pages[m_nSelection];
802
803 if (!pPage->HandleWindowEvent(rEvent))
804 {
805 pPage->SetFocus();
806 }
807 //else: page manages focus inside it itself
808 }
809 else
810 {
811 //
812 // We have no pages - still have to give focus to _something_
813 //
814 SetFocus();
815 }
816 }
817 else
818 {
819 //
820 // It comes from our child, case (a), pass to the parent
821 //
822 if (pParent)
823 {
824 rEvent.SetCurrentFocus(this);
825 pParent->HandleWindowEvent(rEvent);
826 }
827 }
828 }
829 } // end of wxNotebook::OnNavigationKey
830
831 // ----------------------------------------------------------------------------
832 // wxNotebook base class virtuals
833 // ----------------------------------------------------------------------------
834
835 //
836 // Override these 2 functions to do nothing: everything is done in OnSize
837 //
838 void wxNotebook::SetConstraintSizes( bool WXUNUSED(bRecurse) )
839 {
840 //
841 // Don't set the sizes of the pages - their correct size is not yet known
842 //
843 wxControl::SetConstraintSizes(false);
844 } // end of wxNotebook::SetConstraintSizes
845
846 bool wxNotebook::DoPhase ( int WXUNUSED(nPhase) )
847 {
848 return true;
849 } // end of wxNotebook::DoPhase
850
851 // ----------------------------------------------------------------------------
852 // wxNotebook Windows message handlers
853 // ----------------------------------------------------------------------------
854 bool wxNotebook::OS2OnScroll ( int nOrientation,
855 WXWORD wSBCode,
856 WXWORD wPos,
857 WXHWND wControl )
858 {
859 //
860 // Don't generate EVT_SCROLLWIN events for the WM_SCROLLs coming from the
861 // up-down control
862 //
863 if (wControl)
864 return false;
865 return wxNotebookBase::OS2OnScroll( nOrientation
866 ,wSBCode
867 ,wPos
868 ,wControl
869 );
870 } // end of wxNotebook::OS2OnScroll
871
872 #endif // wxUSE_NOTEBOOK