]> git.saurik.com Git - wxWidgets.git/blame - src/os2/notebook.cpp
Don't specialize std::numeric_limits<> for wxLongLong when using VC6.
[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 76 m_imageList = NULL;
f289196b
DW
77 m_nTabSize = 0;
78} // end of wxNotebook::Init
0e320a79 79
f289196b
DW
80//
81// Default for dynamic class
82//
0e320a79
DW
83wxNotebook::wxNotebook()
84{
85 Init();
f289196b
DW
86} // end of wxNotebook::wxNotebook
87
88//
89// The same arguments as for wxControl
90//
91wxNotebook::wxNotebook(
92 wxWindow* pParent
93, wxWindowID vId
94, const wxPoint& rPos
95, const wxSize& rSize
96, long lStyle
97, const wxString& rsName
98)
0e320a79
DW
99{
100 Init();
f289196b
DW
101 Create( pParent
102 ,vId
103 ,rPos
104 ,rSize
105 ,lStyle
106 ,rsName
107 );
108} // end of wxNotebook::wxNotebook
109
110//
0e320a79 111// Create() function
f289196b 112//
6670f564
WS
113bool wxNotebook::Create( wxWindow* pParent,
114 wxWindowID vId,
115 const wxPoint& rPos,
116 const wxSize& rSize,
117 long lStyle,
118 const wxString& rsName )
0e320a79 119{
90f9b8ef
JS
120 if ( (lStyle & wxBK_ALIGN_MASK) == wxBK_DEFAULT )
121 lStyle |= wxBK_TOP;
f289196b
DW
122 //
123 // Base init
124 //
125 if (!CreateControl( pParent
126 ,vId
127 ,rPos
128 ,rSize
129 ,lStyle
130 ,wxDefaultValidator
131 ,rsName
132 ))
6670f564 133 return false;
f289196b
DW
134
135 //
136 // Notebook, so explicitly specify 0 as last parameter
137 //
0fba44b4
DW
138 if (!OS2CreateControl( wxT("NOTEBOOK")
139 ,wxEmptyString
f289196b
DW
140 ,rPos
141 ,rSize
142 ,lStyle | wxTAB_TRAVERSAL
143 ))
6670f564 144 return false;
f289196b
DW
145
146 SetBackgroundColour(wxColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)));
6670f564 147 return true;
f289196b
DW
148} // end of wxNotebook::Create
149
150WXDWORD wxNotebook::OS2GetStyle (
151 long lStyle
152, WXDWORD* pdwExstyle
153) const
0e320a79 154{
f289196b
DW
155 WXDWORD dwTabStyle = wxControl::OS2GetStyle( lStyle
156 ,pdwExstyle
157 );
158
52df30cf 159 dwTabStyle |= WS_TABSTOP | BKS_SOLIDBIND | BKS_ROUNDEDTABS | BKS_TABTEXTCENTER | BKS_TABBEDDIALOG;
f289196b 160
90c0f5a9 161 if (lStyle & wxBK_BOTTOM)
f289196b 162 dwTabStyle |= BKS_MAJORTABBOTTOM | BKS_BACKPAGESBL;
90c0f5a9 163 else if (lStyle & wxBK_RIGHT)
f289196b 164 dwTabStyle |= BKS_MAJORTABRIGHT | BKS_BACKPAGESBR;
90c0f5a9 165 else if (lStyle & wxBK_LEFT)
f289196b
DW
166 dwTabStyle |= BKS_MAJORTABLEFT | BKS_BACKPAGESTL;
167 else // default to top
168 dwTabStyle |= BKS_MAJORTABTOP | BKS_BACKPAGESTR;
169
170 //
171 // Ex style
172 //
173 if (pdwExstyle )
174 {
175 //
176 // Note that we never want to have the default WS_EX_CLIENTEDGE style
177 // as it looks too ugly for the notebooks
178 //
179 *pdwExstyle = 0;
180 }
181 return dwTabStyle;
182} // end of wxNotebook::OS2GetStyle
0e320a79
DW
183
184// ----------------------------------------------------------------------------
185// wxNotebook accessors
186// ----------------------------------------------------------------------------
f289196b 187
21323df7 188size_t wxNotebook::GetPageCount() const
0e320a79 189{
f289196b
DW
190 //
191 // Consistency check
192 //
193 wxASSERT((int)m_pages.Count() == (int)::WinSendMsg(GetHWND(), BKM_QUERYPAGECOUNT, (MPARAM)0, (MPARAM)BKA_END));
194 return m_pages.Count();
195} // end of wxNotebook::GetPageCount
0e320a79
DW
196
197int wxNotebook::GetRowCount() const
198{
f289196b
DW
199 return (int)::WinSendMsg( GetHWND()
200 ,BKM_QUERYPAGECOUNT
201 ,(MPARAM)0
202 ,(MPARAM)BKA_MAJOR
203 );
204} // end of wxNotebook::GetRowCount
205
6670f564 206int wxNotebook::SetSelection( size_t nPage )
0e320a79 207{
90c0f5a9 208 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
f289196b 209
681be2ef 210 if (nPage != (size_t)m_selection)
2b5f62a0 211 {
3e97a905 212 wxBookCtrlEvent vEvent( wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING
2b5f62a0
VZ
213 ,m_windowId
214 );
f289196b 215
2b5f62a0 216 vEvent.SetSelection(nPage);
681be2ef 217 vEvent.SetOldSelection(m_selection);
2b5f62a0 218 vEvent.SetEventObject(this);
937013e0 219 if (!HandleWindowEvent(vEvent) || vEvent.IsAllowed())
2b5f62a0 220 {
f289196b 221
2b5f62a0
VZ
222 //
223 // Program allows the page change
224 //
225 vEvent.SetEventType(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED);
937013e0 226 HandleWindowEvent(vEvent);
2b5f62a0 227
2b5f62a0
VZ
228 ::WinSendMsg( GetHWND()
229 ,BKM_TURNTOPAGE
230 ,MPFROMLONG((ULONG)m_alPageId[nPage])
231 ,(MPARAM)0
232 );
233 }
234 }
681be2ef 235 m_selection = nPage;
f289196b
DW
236 return nPage;
237} // end of wxNotebook::SetSelection
238
1d6fcbcc
VZ
239int wxNotebook::ChangeSelection( size_t nPage )
240{
241 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
242
681be2ef 243 if (nPage != (size_t)m_selection)
1d6fcbcc
VZ
244 {
245 ::WinSendMsg( GetHWND()
246 ,BKM_TURNTOPAGE
247 ,MPFROMLONG((ULONG)m_alPageId[nPage])
248 ,(MPARAM)0
249 );
250 }
681be2ef 251 m_selection = nPage;
1d6fcbcc
VZ
252 return nPage;
253}
254
6670f564
WS
255bool wxNotebook::SetPageText( size_t nPage,
256 const wxString& rsStrText )
f289196b 257{
90c0f5a9 258 wxCHECK_MSG( IS_VALID_PAGE(nPage), false, wxT("notebook page out of range") );
f289196b
DW
259 return (bool)::WinSendMsg( m_hWnd
260 ,BKM_SETTABTEXT
261 ,MPFROMLONG((ULONG)m_alPageId[nPage])
0be0990e 262 ,MPFROMP((const char*)rsStrText.c_str())
f289196b
DW
263 );
264} // end of wxNotebook::SetPageText
0e320a79 265
6670f564 266wxString wxNotebook::GetPageText ( size_t nPage ) const
0e320a79 267{
f289196b
DW
268 BOOKTEXT vBookText;
269 wxChar zBuf[256];
270 wxString sStr;
271 ULONG ulRc;
0e320a79 272
90c0f5a9 273 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxEmptyString, wxT("notebook page out of range") );
0e320a79 274
f289196b
DW
275 memset(&vBookText, '\0', sizeof(BOOKTEXT));
276 vBookText.textLen = 0; // This will get the length
277 ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
278 ,BKM_QUERYTABTEXT
279 ,MPFROMLONG((ULONG)m_alPageId[nPage])
280 ,MPFROMP(&vBookText)
281 ));
9923c37d 282 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
f289196b 283 {
9923c37d 284 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS)
f289196b
DW
285 {
286 wxLogError(wxT("Invalid Page Id for page text querry."));
287 }
288 return wxEmptyString;
289 }
290 vBookText.textLen = ulRc + 1; // To get the null terminator
0fba44b4 291 vBookText.pString = (char*)zBuf;
f289196b
DW
292
293 //
294 // Now get the actual text
295 //
296 ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
297 ,BKM_QUERYTABTEXT
298 ,MPFROMLONG((ULONG)m_alPageId[nPage])
299 ,MPFROMP(&vBookText)
300 ));
9923c37d 301 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
f289196b
DW
302 {
303 return wxEmptyString;
304 }
305 if (ulRc > 255L)
306 ulRc = 255L;
307
308 vBookText.pString[ulRc] = '\0';
0fba44b4 309 sStr = (wxChar*)vBookText.pString;
f289196b
DW
310 return sStr;
311} // end of wxNotebook::GetPageText
312
6670f564 313int wxNotebook::GetPageImage ( size_t nPage ) const
0e320a79 314{
90c0f5a9 315 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
0e320a79 316
f289196b
DW
317 //
318 // For OS/2 just return the page
319 //
320 return nPage;
321} // end of wxNotebook::GetPageImage
0e320a79 322
f289196b 323bool wxNotebook::SetPageImage (
3979bf6b 324 size_t nPage
f289196b
DW
325, int nImage
326)
0e320a79 327{
0d598bae 328 wxBitmap vBitmap = (wxBitmap)m_imageList->GetBitmap(nImage);
0e320a79 329
f289196b
DW
330 return (bool)::WinSendMsg( GetHWND()
331 ,BKM_SETTABBITMAP
332 ,MPFROMLONG((ULONG)m_alPageId[nPage])
a4e15a8d 333 ,(MPARAM)wxCopyBmp(vBitmap.GetHBITMAP(), true)
f289196b
DW
334 );
335} // end of wxNotebook::SetPageImage
336
337void wxNotebook::SetImageList (
ab5ebf52 338 wxImageList* pImageList
f289196b 339)
cdf1e714 340{
6670f564 341 //
ab5ebf52
SN
342 // Does not really do anything yet, but at least we need to
343 // update the base class.
6670f564 344 //
ab5ebf52 345 wxNotebookBase::SetImageList(pImageList);
f289196b 346} // end of wxNotebook::SetImageList
cdf1e714 347
0e320a79 348// ----------------------------------------------------------------------------
f289196b 349// wxNotebook size settings
0e320a79 350// ----------------------------------------------------------------------------
f289196b
DW
351void wxNotebook::SetPageSize (
352 const wxSize& rSize
353)
0367c1c0 354{
52df30cf 355 SetSize(rSize);
f289196b
DW
356} // end of wxNotebook::SetPageSize
357
358void wxNotebook::SetPadding (
359 const wxSize& WXUNUSED(rPadding)
360)
0367c1c0 361{
f289196b
DW
362 //
363 // No padding in OS/2
364 //
365} // end of wxNotebook::SetPadding
366
367void wxNotebook::SetTabSize (
368 const wxSize& rSize
369)
370{
371 ::WinSendMsg( GetHWND()
372 ,BKM_SETDIMENSIONS
373 ,MPFROM2SHORT( (USHORT)rSize.x
374 ,(USHORT)rSize.y
375 )
376 ,(MPARAM)BKA_MAJORTAB
377 );
378} // end of wxNotebook::SetTabSize
379
380// ----------------------------------------------------------------------------
381// wxNotebook operations
382// ----------------------------------------------------------------------------
0367c1c0 383
f289196b
DW
384//
385// Remove one page from the notebook, without deleting
386//
6670f564 387wxNotebookPage* wxNotebook::DoRemovePage ( size_t nPage )
0e320a79 388{
6670f564 389 wxNotebookPage* pPageRemoved = wxNotebookBase::DoRemovePage(nPage);
0e320a79 390
f289196b
DW
391 if (!pPageRemoved)
392 return NULL;
0e320a79 393
f289196b
DW
394 ::WinSendMsg( GetHWND()
395 ,BKM_DELETEPAGE
396 ,MPFROMLONG((ULONG)m_alPageId[nPage])
397 ,(MPARAM)BKA_TAB
398 );
399 if (m_pages.IsEmpty())
400 {
401 //
402 // No selection any more, the notebook becamse empty
403 //
681be2ef 404 m_selection = wxNOT_FOUND;
f289196b
DW
405 }
406 else // notebook still not empty
407 {
408 //
409 // Change the selected page if it was deleted or became invalid
410 //
411 int nSelNew;
0e320a79 412
681be2ef 413 if (m_selection == (int)GetPageCount())
f289196b
DW
414 {
415 //
416 // Last page deleted, make the new last page the new selection
417 //
681be2ef 418 nSelNew = m_selection - 1;
f289196b 419 }
681be2ef 420 else if (nPage <= (size_t)m_selection)
f289196b
DW
421 {
422 //
423 // We must show another page, even if it has the same index
424 //
681be2ef 425 nSelNew = m_selection;
f289196b
DW
426 }
427 else // nothing changes for the currently selected page
428 {
7e837615 429 nSelNew = wxNOT_FOUND;
f289196b
DW
430
431 //
432 // We still must refresh the current page: this needs to be done
433 // for some unknown reason if the tab control shows the up-down
434 // control (i.e. when there are too many pages) -- otherwise after
435 // deleting a page nothing at all is shown
436 //
681be2ef 437 m_pages[m_selection]->Refresh();
f289196b 438 }
0e320a79 439
7e837615 440 if (nSelNew != wxNOT_FOUND)
f289196b
DW
441 {
442 //
681be2ef 443 // m_selection must be always valid so reset it before calling
f289196b
DW
444 // SetSelection()
445 //
681be2ef 446 m_selection = wxNOT_FOUND;
f289196b
DW
447 SetSelection(nSelNew);
448 }
449 }
450 return pPageRemoved;
451} // end of wxNotebook::DoRemovePage
0e320a79 452
f289196b
DW
453//
454// Remove all pages
455//
0e320a79
DW
456bool wxNotebook::DeleteAllPages()
457{
f289196b
DW
458 int nPageCount = GetPageCount();
459 int nPage;
460
461 for (nPage = 0; nPage < nPageCount; nPage++)
462 delete m_pages[nPage];
463 m_pages.Clear();
464 ::WinSendMsg( GetHWND()
465 ,BKM_DELETEPAGE
466 ,(MPARAM)0
467 ,(MPARAM)BKA_ALL
468 );
681be2ef 469 m_selection = wxNOT_FOUND;
6670f564
WS
470
471 return true;
f289196b
DW
472} // end of wxNotebook::DeleteAllPages
473
474//
475// Add a page to the notebook
476//
477bool wxNotebook::AddPage (
478 wxNotebookPage* pPage
479, const wxString& rStrText
480, bool bSelect
481, int nImageId
482)
0e320a79 483{
f289196b
DW
484 return InsertPage( GetPageCount()
485 ,pPage
486 ,rStrText
487 ,bSelect
488 ,nImageId
489 );
490} // end of wxNotebook::AddPage
491
492//
493// Same as AddPage() but does it at given position
494//
6670f564
WS
495bool wxNotebook::InsertPage ( size_t nPage,
496 wxNotebookPage* pPage,
497 const wxString& rsStrText,
498 bool bSelect,
499 int nImageId )
0e320a79 500{
f289196b
DW
501 ULONG ulApiPage;
502
0e320a79 503 wxASSERT( pPage != NULL );
90c0f5a9 504 wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), false );
0e320a79 505
f289196b
DW
506 //
507 // Under OS/2 we can only insert FIRST, LAST, NEXT or PREV. Requires
508 // two different calls to the API. Page 1 uses the BKA_FIRST. Subsequent
509 // pages use the previous page ID coupled with a BKA_NEXT call. Unlike
510 // Windows, OS/2 uses an internal Page ID to ID the pages.
511 //
512 // OS/2 also has a nice auto-size feature that automatically sizes the
513 // the attached window so we don't have to worry about the size of the
514 // window on the page.
515 //
516 if (nPage == 0)
517 {
518 ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
519 ,BKM_INSERTPAGE
520 ,(MPARAM)0
521 ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_FIRST)
522 ));
523 if (ulApiPage == 0L)
524 {
525 ERRORID vError;
526 wxString sError;
0e320a79 527
f289196b
DW
528 vError = ::WinGetLastError(vHabmain);
529 sError = wxPMErrorToStr(vError);
90c0f5a9 530 return false;
f289196b
DW
531 }
532 m_alPageId.Insert((long)ulApiPage, nPage);
533 }
534 else
535 {
536 ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
537 ,BKM_INSERTPAGE
538 ,MPFROMLONG((ULONG)m_alPageId[nPage - 1])
539 ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_NEXT)
540 ));
541 if (ulApiPage == 0L)
542 {
543 ERRORID vError;
544 wxString sError;
0e320a79 545
f289196b
DW
546 vError = ::WinGetLastError(vHabmain);
547 sError = wxPMErrorToStr(vError);
90c0f5a9 548 return false;
f289196b
DW
549 }
550 m_alPageId.Insert((long)ulApiPage, nPage);
551 }
0e320a79 552
f289196b
DW
553 //
554 // Associate a window handle with the page
555 //
556 if (pPage)
557 {
558 if (!::WinSendMsg( GetHWND()
559 ,BKM_SETPAGEWINDOWHWND
560 ,MPFROMLONG((ULONG)m_alPageId[nPage])
561 ,MPFROMHWND(pPage->GetHWND())
562 ))
90c0f5a9 563 return false;
f289196b
DW
564 }
565 //
566 // If the inserted page is before the selected one, we must update the
567 // index of the selected page
568 //
681be2ef 569 if (nPage <= (size_t)m_selection)
f289196b
DW
570 {
571 //
572 // One extra page added
573 //
681be2ef 574 m_selection++;
f289196b 575 }
0e320a79 576
f289196b
DW
577 if (pPage)
578 {
579 //
580 // Save the pointer to the page
581 //
582 m_pages.Insert( pPage
583 ,nPage
584 );
0e320a79
DW
585 }
586
f289196b
DW
587 //
588 // Now set TAB dimenstions
589 //
0e320a79 590
6670f564
WS
591 wxWindowDC vDC(this);
592 wxCoord nTextX;
593 wxCoord nTextY;
0e320a79 594
f289196b
DW
595 vDC.GetTextExtent(rsStrText, &nTextX, &nTextY);
596 nTextY *= 2;
9923c37d 597 nTextX = (wxCoord)(nTextX * 1.3);
f289196b
DW
598 if (nTextX > m_nTabSize)
599 {
600 m_nTabSize = nTextX;
601 ::WinSendMsg( GetHWND()
602 ,BKM_SETDIMENSIONS
603 ,MPFROM2SHORT((USHORT)m_nTabSize, (USHORT)nTextY)
604 ,(MPARAM)BKA_MAJORTAB
605 );
606 }
607 //
608 // Now set any TAB text
609 //
6670f564 610 if (!rsStrText.empty())
f289196b
DW
611 {
612 if (!SetPageText( nPage
613 ,rsStrText
614 ))
90c0f5a9 615 return false;
f289196b 616 }
0e320a79 617
f289196b
DW
618 //
619 // Now set any TAB bitmap image
620 //
621 if (nImageId != -1)
622 {
623 if (!SetPageImage( nPage
624 ,nImageId
625 ))
90c0f5a9 626 return false;
f289196b 627 }
7e99520b 628
f289196b
DW
629 if (pPage)
630 {
631 //
632 // Don't show pages by default (we'll need to adjust their size first)
633 //
90c0f5a9 634 HWND hWnd = GetWinHwnd(pPage);
f289196b
DW
635
636 WinSetWindowULong( hWnd
637 ,QWL_STYLE
638 ,WinQueryWindowULong( hWnd
639 ,QWL_STYLE
640 ) & ~WS_VISIBLE
641 );
642
643 //
644 // This updates internal flag too - otherwise it will get out of sync
645 //
90c0f5a9 646 pPage->Show(false);
0e320a79
DW
647 }
648
60d5c563 649 DoSetSelectionAfterInsertion(nPage, bSelect);
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 (
3e97a905 667 wxBookCtrlEvent& rEvent
f289196b
DW
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);
681be2ef 713 m_selection = nSel;
f289196b 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 733 //
681be2ef
VZ
734 if (m_selection != wxNOT_FOUND)
735 m_pages[m_selection]->SetFocus();
f289196b
DW
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 //
681be2ef 774 if (m_selection != wxNOT_FOUND)
f289196b
DW
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
681be2ef 782 wxWindow* pPage = m_pages[m_selection];
f289196b 783
937013e0 784 if (!pPage->HandleWindowEvent(rEvent))
f289196b
DW
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);
937013e0 806 pParent->HandleWindowEvent(rEvent);
f289196b 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