]> git.saurik.com Git - wxWidgets.git/blame - src/os2/notebook.cpp
Read TIFF images from top to bottom instead of bottom to top.
[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
e4db172a
WS
17#include "wx/notebook.h"
18
77ffb593 19// wxWidgets
cdf1e714 20#ifndef WX_PRECOMP
e4db172a
WS
21 #include "wx/app.h"
22 #include "wx/dcclient.h"
23 #include "wx/string.h"
24 #include "wx/settings.h"
d5da0ce7
WS
25 #include "wx/log.h"
26 #include "wx/event.h"
93fbbe07 27 #include "wx/control.h"
cdf1e714 28#endif // WX_PRECOMP
0e320a79 29
f289196b 30#include "wx/imaglist.h"
cdf1e714 31
f289196b 32#include "wx/os2/private.h"
cdf1e714 33
0e320a79
DW
34// ----------------------------------------------------------------------------
35// macros
36// ----------------------------------------------------------------------------
f289196b 37
0e320a79 38// check that the page index is valid
6670f564
WS
39#define IS_VALID_PAGE(nPage) ( \
40 /* size_t is _always_ >= 0 */ \
41 /* ((nPage) >= 0) && */ \
42 ((nPage) < GetPageCount()) \
43 )
0e320a79 44
cdf1e714 45// hide the ugly cast
f289196b 46#define m_hWnd (HWND)GetHWND()
cdf1e714
DW
47
48// ----------------------------------------------------------------------------
49// constants
50// ----------------------------------------------------------------------------
51
0e320a79
DW
52// ----------------------------------------------------------------------------
53// event table
54// ----------------------------------------------------------------------------
55
8dba4c72 56BEGIN_EVENT_TABLE(wxNotebook, wxBookCtrlBase)
90c0f5a9 57 EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, wxNotebook::OnSelChange)
0e320a79
DW
58 EVT_SIZE(wxNotebook::OnSize)
59 EVT_SET_FOCUS(wxNotebook::OnSetFocus)
60 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
8546f11e 61END_EVENT_TABLE()
0e320a79 62
0e320a79
DW
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
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 111//
6670f564
WS
112bool wxNotebook::Create( wxWindow* pParent,
113 wxWindowID vId,
114 const wxPoint& rPos,
115 const wxSize& rSize,
116 long lStyle,
117 const wxString& rsName )
0e320a79 118{
90f9b8ef
JS
119 if ( (lStyle & wxBK_ALIGN_MASK) == wxBK_DEFAULT )
120 lStyle |= wxBK_TOP;
f289196b
DW
121 //
122 // Base init
123 //
124 if (!CreateControl( pParent
125 ,vId
126 ,rPos
127 ,rSize
128 ,lStyle
129 ,wxDefaultValidator
130 ,rsName
131 ))
6670f564 132 return false;
f289196b
DW
133
134 //
135 // Notebook, so explicitly specify 0 as last parameter
136 //
0fba44b4
DW
137 if (!OS2CreateControl( wxT("NOTEBOOK")
138 ,wxEmptyString
f289196b
DW
139 ,rPos
140 ,rSize
141 ,lStyle | wxTAB_TRAVERSAL
142 ))
6670f564 143 return false;
f289196b
DW
144
145 SetBackgroundColour(wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
6670f564 146 return true;
f289196b
DW
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
52df30cf 158 dwTabStyle |= WS_TABSTOP | BKS_SOLIDBIND | BKS_ROUNDEDTABS | BKS_TABTEXTCENTER | BKS_TABBEDDIALOG;
f289196b 159
90c0f5a9 160 if (lStyle & wxBK_BOTTOM)
f289196b 161 dwTabStyle |= BKS_MAJORTABBOTTOM | BKS_BACKPAGESBL;
90c0f5a9 162 else if (lStyle & wxBK_RIGHT)
f289196b 163 dwTabStyle |= BKS_MAJORTABRIGHT | BKS_BACKPAGESBR;
90c0f5a9 164 else if (lStyle & wxBK_LEFT)
f289196b
DW
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
21323df7 187size_t wxNotebook::GetPageCount() const
0e320a79 188{
f289196b
DW
189 //
190 // Consistency check
191 //
192 wxASSERT((int)m_pages.Count() == (int)::WinSendMsg(GetHWND(), BKM_QUERYPAGECOUNT, (MPARAM)0, (MPARAM)BKA_END));
193 return m_pages.Count();
194} // end of wxNotebook::GetPageCount
0e320a79
DW
195
196int wxNotebook::GetRowCount() const
197{
f289196b
DW
198 return (int)::WinSendMsg( GetHWND()
199 ,BKM_QUERYPAGECOUNT
200 ,(MPARAM)0
201 ,(MPARAM)BKA_MAJOR
202 );
203} // end of wxNotebook::GetRowCount
204
6670f564 205int wxNotebook::SetSelection( size_t nPage )
0e320a79 206{
90c0f5a9 207 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
f289196b 208
681be2ef 209 if (nPage != (size_t)m_selection)
2b5f62a0 210 {
3e97a905 211 wxBookCtrlEvent vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING
2b5f62a0
VZ
212 ,m_windowId
213 );
f289196b 214
2b5f62a0 215 vEvent.SetSelection(nPage);
681be2ef 216 vEvent.SetOldSelection(m_selection);
2b5f62a0 217 vEvent.SetEventObject(this);
937013e0 218 if (!HandleWindowEvent(vEvent) || vEvent.IsAllowed())
2b5f62a0 219 {
f289196b 220
2b5f62a0
VZ
221 //
222 // Program allows the page change
223 //
224 vEvent.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
937013e0 225 HandleWindowEvent(vEvent);
2b5f62a0 226
2b5f62a0
VZ
227 ::WinSendMsg( GetHWND()
228 ,BKM_TURNTOPAGE
229 ,MPFROMLONG((ULONG)m_alPageId[nPage])
230 ,(MPARAM)0
231 );
232 }
233 }
681be2ef 234 m_selection = nPage;
f289196b
DW
235 return nPage;
236} // end of wxNotebook::SetSelection
237
1d6fcbcc
VZ
238int wxNotebook::ChangeSelection( size_t nPage )
239{
240 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
241
681be2ef 242 if (nPage != (size_t)m_selection)
1d6fcbcc
VZ
243 {
244 ::WinSendMsg( GetHWND()
245 ,BKM_TURNTOPAGE
246 ,MPFROMLONG((ULONG)m_alPageId[nPage])
247 ,(MPARAM)0
248 );
249 }
681be2ef 250 m_selection = nPage;
1d6fcbcc
VZ
251 return nPage;
252}
253
6670f564
WS
254bool wxNotebook::SetPageText( size_t nPage,
255 const wxString& rsStrText )
f289196b 256{
90c0f5a9 257 wxCHECK_MSG( IS_VALID_PAGE(nPage), false, wxT("notebook page out of range") );
f289196b
DW
258 return (bool)::WinSendMsg( m_hWnd
259 ,BKM_SETTABTEXT
260 ,MPFROMLONG((ULONG)m_alPageId[nPage])
0be0990e 261 ,MPFROMP((const char*)rsStrText.c_str())
f289196b
DW
262 );
263} // end of wxNotebook::SetPageText
0e320a79 264
6670f564 265wxString wxNotebook::GetPageText ( size_t nPage ) const
0e320a79 266{
f289196b
DW
267 BOOKTEXT vBookText;
268 wxChar zBuf[256];
269 wxString sStr;
270 ULONG ulRc;
0e320a79 271
90c0f5a9 272 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxEmptyString, wxT("notebook page out of range") );
0e320a79 273
f289196b
DW
274 memset(&vBookText, '\0', sizeof(BOOKTEXT));
275 vBookText.textLen = 0; // This will get the length
276 ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
277 ,BKM_QUERYTABTEXT
278 ,MPFROMLONG((ULONG)m_alPageId[nPage])
279 ,MPFROMP(&vBookText)
280 ));
9923c37d 281 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
f289196b 282 {
9923c37d 283 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS)
f289196b
DW
284 {
285 wxLogError(wxT("Invalid Page Id for page text querry."));
286 }
287 return wxEmptyString;
288 }
289 vBookText.textLen = ulRc + 1; // To get the null terminator
0fba44b4 290 vBookText.pString = (char*)zBuf;
f289196b
DW
291
292 //
293 // Now get the actual text
294 //
295 ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
296 ,BKM_QUERYTABTEXT
297 ,MPFROMLONG((ULONG)m_alPageId[nPage])
298 ,MPFROMP(&vBookText)
299 ));
9923c37d 300 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
f289196b
DW
301 {
302 return wxEmptyString;
303 }
304 if (ulRc > 255L)
305 ulRc = 255L;
306
307 vBookText.pString[ulRc] = '\0';
0fba44b4 308 sStr = (wxChar*)vBookText.pString;
f289196b
DW
309 return sStr;
310} // end of wxNotebook::GetPageText
311
6670f564 312int wxNotebook::GetPageImage ( size_t nPage ) const
0e320a79 313{
90c0f5a9 314 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
0e320a79 315
f289196b
DW
316 //
317 // For OS/2 just return the page
318 //
319 return nPage;
320} // end of wxNotebook::GetPageImage
0e320a79 321
f289196b 322bool wxNotebook::SetPageImage (
3979bf6b 323 size_t nPage
f289196b
DW
324, int nImage
325)
0e320a79 326{
3f4880a4 327 wxBitmap vBitmap = (wxBitmap)GetImageList()->GetBitmap(nImage);
0e320a79 328
f289196b
DW
329 return (bool)::WinSendMsg( GetHWND()
330 ,BKM_SETTABBITMAP
331 ,MPFROMLONG((ULONG)m_alPageId[nPage])
a4e15a8d 332 ,(MPARAM)wxCopyBmp(vBitmap.GetHBITMAP(), true)
f289196b
DW
333 );
334} // end of wxNotebook::SetPageImage
335
336void wxNotebook::SetImageList (
ab5ebf52 337 wxImageList* pImageList
f289196b 338)
cdf1e714 339{
6670f564 340 //
ab5ebf52
SN
341 // Does not really do anything yet, but at least we need to
342 // update the base class.
6670f564 343 //
ab5ebf52 344 wxNotebookBase::SetImageList(pImageList);
f289196b 345} // end of wxNotebook::SetImageList
cdf1e714 346
0e320a79 347// ----------------------------------------------------------------------------
f289196b 348// wxNotebook size settings
0e320a79 349// ----------------------------------------------------------------------------
f289196b
DW
350void wxNotebook::SetPageSize (
351 const wxSize& rSize
352)
0367c1c0 353{
52df30cf 354 SetSize(rSize);
f289196b
DW
355} // end of wxNotebook::SetPageSize
356
357void wxNotebook::SetPadding (
358 const wxSize& WXUNUSED(rPadding)
359)
0367c1c0 360{
f289196b
DW
361 //
362 // No padding in OS/2
363 //
364} // end of wxNotebook::SetPadding
365
366void wxNotebook::SetTabSize (
367 const wxSize& rSize
368)
369{
370 ::WinSendMsg( GetHWND()
371 ,BKM_SETDIMENSIONS
372 ,MPFROM2SHORT( (USHORT)rSize.x
373 ,(USHORT)rSize.y
374 )
375 ,(MPARAM)BKA_MAJORTAB
376 );
377} // end of wxNotebook::SetTabSize
378
379// ----------------------------------------------------------------------------
380// wxNotebook operations
381// ----------------------------------------------------------------------------
0367c1c0 382
f289196b
DW
383//
384// Remove one page from the notebook, without deleting
385//
6670f564 386wxNotebookPage* wxNotebook::DoRemovePage ( size_t nPage )
0e320a79 387{
6670f564 388 wxNotebookPage* pPageRemoved = wxNotebookBase::DoRemovePage(nPage);
0e320a79 389
f289196b
DW
390 if (!pPageRemoved)
391 return NULL;
0e320a79 392
f289196b
DW
393 ::WinSendMsg( GetHWND()
394 ,BKM_DELETEPAGE
395 ,MPFROMLONG((ULONG)m_alPageId[nPage])
396 ,(MPARAM)BKA_TAB
397 );
398 if (m_pages.IsEmpty())
399 {
400 //
401 // No selection any more, the notebook becamse empty
402 //
681be2ef 403 m_selection = wxNOT_FOUND;
f289196b
DW
404 }
405 else // notebook still not empty
406 {
407 //
408 // Change the selected page if it was deleted or became invalid
409 //
410 int nSelNew;
0e320a79 411
681be2ef 412 if (m_selection == (int)GetPageCount())
f289196b
DW
413 {
414 //
415 // Last page deleted, make the new last page the new selection
416 //
681be2ef 417 nSelNew = m_selection - 1;
f289196b 418 }
681be2ef 419 else if (nPage <= (size_t)m_selection)
f289196b
DW
420 {
421 //
422 // We must show another page, even if it has the same index
423 //
681be2ef 424 nSelNew = m_selection;
f289196b
DW
425 }
426 else // nothing changes for the currently selected page
427 {
7e837615 428 nSelNew = wxNOT_FOUND;
f289196b
DW
429
430 //
431 // We still must refresh the current page: this needs to be done
432 // for some unknown reason if the tab control shows the up-down
433 // control (i.e. when there are too many pages) -- otherwise after
434 // deleting a page nothing at all is shown
435 //
681be2ef 436 m_pages[m_selection]->Refresh();
f289196b 437 }
0e320a79 438
7e837615 439 if (nSelNew != wxNOT_FOUND)
f289196b
DW
440 {
441 //
681be2ef 442 // m_selection must be always valid so reset it before calling
f289196b
DW
443 // SetSelection()
444 //
681be2ef 445 m_selection = wxNOT_FOUND;
f289196b
DW
446 SetSelection(nSelNew);
447 }
448 }
449 return pPageRemoved;
450} // end of wxNotebook::DoRemovePage
0e320a79 451
f289196b
DW
452//
453// Remove all pages
454//
0e320a79
DW
455bool wxNotebook::DeleteAllPages()
456{
f289196b
DW
457 int nPageCount = GetPageCount();
458 int nPage;
459
460 for (nPage = 0; nPage < nPageCount; nPage++)
461 delete m_pages[nPage];
462 m_pages.Clear();
463 ::WinSendMsg( GetHWND()
464 ,BKM_DELETEPAGE
465 ,(MPARAM)0
466 ,(MPARAM)BKA_ALL
467 );
681be2ef 468 m_selection = wxNOT_FOUND;
6670f564
WS
469
470 return true;
f289196b
DW
471} // end of wxNotebook::DeleteAllPages
472
473//
474// Add a page to the notebook
475//
476bool wxNotebook::AddPage (
477 wxNotebookPage* pPage
478, const wxString& rStrText
479, bool bSelect
480, int nImageId
481)
0e320a79 482{
f289196b
DW
483 return InsertPage( GetPageCount()
484 ,pPage
485 ,rStrText
486 ,bSelect
487 ,nImageId
488 );
489} // end of wxNotebook::AddPage
490
491//
492// Same as AddPage() but does it at given position
493//
6670f564
WS
494bool wxNotebook::InsertPage ( size_t nPage,
495 wxNotebookPage* pPage,
496 const wxString& rsStrText,
497 bool bSelect,
498 int nImageId )
0e320a79 499{
f289196b
DW
500 ULONG ulApiPage;
501
0e320a79 502 wxASSERT( pPage != NULL );
90c0f5a9 503 wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), false );
0e320a79 504
f289196b
DW
505 //
506 // Under OS/2 we can only insert FIRST, LAST, NEXT or PREV. Requires
507 // two different calls to the API. Page 1 uses the BKA_FIRST. Subsequent
508 // pages use the previous page ID coupled with a BKA_NEXT call. Unlike
509 // Windows, OS/2 uses an internal Page ID to ID the pages.
510 //
511 // OS/2 also has a nice auto-size feature that automatically sizes the
512 // the attached window so we don't have to worry about the size of the
513 // window on the page.
514 //
515 if (nPage == 0)
516 {
517 ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
518 ,BKM_INSERTPAGE
519 ,(MPARAM)0
520 ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_FIRST)
521 ));
522 if (ulApiPage == 0L)
523 {
524 ERRORID vError;
525 wxString sError;
0e320a79 526
f289196b
DW
527 vError = ::WinGetLastError(vHabmain);
528 sError = wxPMErrorToStr(vError);
90c0f5a9 529 return false;
f289196b
DW
530 }
531 m_alPageId.Insert((long)ulApiPage, nPage);
532 }
533 else
534 {
535 ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
536 ,BKM_INSERTPAGE
537 ,MPFROMLONG((ULONG)m_alPageId[nPage - 1])
538 ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_NEXT)
539 ));
540 if (ulApiPage == 0L)
541 {
542 ERRORID vError;
543 wxString sError;
0e320a79 544
f289196b
DW
545 vError = ::WinGetLastError(vHabmain);
546 sError = wxPMErrorToStr(vError);
90c0f5a9 547 return false;
f289196b
DW
548 }
549 m_alPageId.Insert((long)ulApiPage, nPage);
550 }
0e320a79 551
f289196b
DW
552 //
553 // Associate a window handle with the page
554 //
555 if (pPage)
556 {
557 if (!::WinSendMsg( GetHWND()
558 ,BKM_SETPAGEWINDOWHWND
559 ,MPFROMLONG((ULONG)m_alPageId[nPage])
560 ,MPFROMHWND(pPage->GetHWND())
561 ))
90c0f5a9 562 return false;
f289196b
DW
563 }
564 //
565 // If the inserted page is before the selected one, we must update the
566 // index of the selected page
567 //
681be2ef 568 if (nPage <= (size_t)m_selection)
f289196b
DW
569 {
570 //
571 // One extra page added
572 //
681be2ef 573 m_selection++;
f289196b 574 }
0e320a79 575
f289196b
DW
576 if (pPage)
577 {
578 //
579 // Save the pointer to the page
580 //
581 m_pages.Insert( pPage
582 ,nPage
583 );
0e320a79
DW
584 }
585
f289196b
DW
586 //
587 // Now set TAB dimenstions
588 //
0e320a79 589
6670f564
WS
590 wxWindowDC vDC(this);
591 wxCoord nTextX;
592 wxCoord nTextY;
0e320a79 593
f289196b
DW
594 vDC.GetTextExtent(rsStrText, &nTextX, &nTextY);
595 nTextY *= 2;
9923c37d 596 nTextX = (wxCoord)(nTextX * 1.3);
f289196b
DW
597 if (nTextX > m_nTabSize)
598 {
599 m_nTabSize = nTextX;
600 ::WinSendMsg( GetHWND()
601 ,BKM_SETDIMENSIONS
602 ,MPFROM2SHORT((USHORT)m_nTabSize, (USHORT)nTextY)
603 ,(MPARAM)BKA_MAJORTAB
604 );
605 }
606 //
607 // Now set any TAB text
608 //
6670f564 609 if (!rsStrText.empty())
f289196b
DW
610 {
611 if (!SetPageText( nPage
612 ,rsStrText
613 ))
90c0f5a9 614 return false;
f289196b 615 }
0e320a79 616
f289196b
DW
617 //
618 // Now set any TAB bitmap image
619 //
620 if (nImageId != -1)
621 {
622 if (!SetPageImage( nPage
623 ,nImageId
624 ))
90c0f5a9 625 return false;
f289196b 626 }
7e99520b 627
f289196b
DW
628 if (pPage)
629 {
630 //
631 // Don't show pages by default (we'll need to adjust their size first)
632 //
90c0f5a9 633 HWND hWnd = GetWinHwnd(pPage);
f289196b
DW
634
635 WinSetWindowULong( hWnd
636 ,QWL_STYLE
637 ,WinQueryWindowULong( hWnd
638 ,QWL_STYLE
639 ) & ~WS_VISIBLE
640 );
641
642 //
643 // This updates internal flag too - otherwise it will get out of sync
644 //
90c0f5a9 645 pPage->Show(false);
0e320a79
DW
646 }
647
60d5c563 648 DoSetSelectionAfterInsertion(nPage, bSelect);
52df30cf
SN
649
650 InvalidateBestSize();
651
90c0f5a9 652 return true;
f289196b
DW
653} // end of wxNotebook::InsertPage
654
655// ----------------------------------------------------------------------------
656// wxNotebook callbacks
657// ----------------------------------------------------------------------------
658void wxNotebook::OnSize(
659 wxSizeEvent& rEvent
660)
0e320a79 661{
f289196b
DW
662 rEvent.Skip();
663} // end of wxNotebook::OnSize
664
665void wxNotebook::OnSelChange (
3e97a905 666 wxBookCtrlEvent& rEvent
f289196b
DW
667)
668{
669 //
670 // Is it our tab control?
671 //
672 if (rEvent.GetEventObject() == this)
cdf1e714 673 {
90c0f5a9
WS
674 int nPageCount = GetPageCount();
675 int nSel;
676 ULONG ulOS2Sel = (ULONG)rEvent.GetOldSelection();
677 bool bFound = false;
fb46a9a6 678
1de4baa3 679 for (nSel = 0; nSel < nPageCount; nSel++)
f289196b 680 {
9923c37d 681 if (ulOS2Sel == (ULONG)m_alPageId[nSel])
1de4baa3 682 {
90c0f5a9 683 bFound = true;
1de4baa3
DW
684 break;
685 }
f289196b 686 }
f289196b 687
1de4baa3
DW
688 if (!bFound)
689 return;
690
90c0f5a9 691 m_pages[nSel]->Show(false);
1de4baa3
DW
692
693 ulOS2Sel = (ULONG)rEvent.GetSelection();
694
90c0f5a9 695 bFound = false;
1de4baa3
DW
696
697 for (nSel = 0; nSel < nPageCount; nSel++)
698 {
9923c37d 699 if (ulOS2Sel == (ULONG)m_alPageId[nSel])
1de4baa3 700 {
90c0f5a9 701 bFound = true;
1de4baa3
DW
702 break;
703 }
cdf1e714 704 }
1de4baa3
DW
705
706 if (!bFound)
707 return;
708
709 wxNotebookPage* pPage = m_pages[nSel];
710
90c0f5a9 711 pPage->Show(true);
681be2ef 712 m_selection = nSel;
f289196b 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 732 //
681be2ef
VZ
733 if (m_selection != wxNOT_FOUND)
734 m_pages[m_selection]->SetFocus();
f289196b
DW
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 //
681be2ef 773 if (m_selection != wxNOT_FOUND)
f289196b
DW
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
681be2ef 781 wxWindow* pPage = m_pages[m_selection];
f289196b 782
937013e0 783 if (!pPage->HandleWindowEvent(rEvent))
f289196b
DW
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);
937013e0 805 pParent->HandleWindowEvent(rEvent);
f289196b 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//
90c0f5a9 818void wxNotebook::SetConstraintSizes( bool WXUNUSED(bRecurse) )
0e320a79 819{
f289196b
DW
820 //
821 // Don't set the sizes of the pages - their correct size is not yet known
822 //
90c0f5a9 823 wxControl::SetConstraintSizes(false);
f289196b 824} // end of wxNotebook::SetConstraintSizes
0e320a79 825
90c0f5a9 826bool wxNotebook::DoPhase ( int WXUNUSED(nPhase) )
0e320a79 827{
90c0f5a9 828 return true;
f289196b 829} // end of wxNotebook::DoPhase
0e320a79 830
f289196b
DW
831// ----------------------------------------------------------------------------
832// wxNotebook Windows message handlers
833// ----------------------------------------------------------------------------
6670f564
WS
834bool wxNotebook::OS2OnScroll ( int nOrientation,
835 WXWORD wSBCode,
836 WXWORD wPos,
837 WXHWND wControl )
0e320a79 838{
f289196b
DW
839 //
840 // Don't generate EVT_SCROLLWIN events for the WM_SCROLLs coming from the
841 // up-down control
842 //
843 if (wControl)
90c0f5a9 844 return false;
f289196b
DW
845 return wxNotebookBase::OS2OnScroll( nOrientation
846 ,wSBCode
847 ,wPos
848 ,wControl
849 );
850} // end of wxNotebook::OS2OnScroll
0e320a79 851
f289196b 852#endif // wxUSE_NOTEBOOK