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