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