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