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