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