]> git.saurik.com Git - wxWidgets.git/blame - src/os2/notebook.cpp
use wxGetLocalTimeMillis() instead of wxDateTime in wxSocketBase::_Wait(), this allow...
[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
1d6fcbcc
VZ
246int wxNotebook::ChangeSelection( size_t nPage )
247{
248 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
249
250 if (nPage != (size_t)m_nSelection)
251 {
252 ::WinSendMsg( GetHWND()
253 ,BKM_TURNTOPAGE
254 ,MPFROMLONG((ULONG)m_alPageId[nPage])
255 ,(MPARAM)0
256 );
257 }
258 m_nSelection = nPage;
259 return nPage;
260}
261
6670f564
WS
262bool wxNotebook::SetPageText( size_t nPage,
263 const wxString& rsStrText )
f289196b 264{
90c0f5a9 265 wxCHECK_MSG( IS_VALID_PAGE(nPage), false, wxT("notebook page out of range") );
f289196b
DW
266 return (bool)::WinSendMsg( m_hWnd
267 ,BKM_SETTABTEXT
268 ,MPFROMLONG((ULONG)m_alPageId[nPage])
0be0990e 269 ,MPFROMP((const char*)rsStrText.c_str())
f289196b
DW
270 );
271} // end of wxNotebook::SetPageText
0e320a79 272
6670f564 273wxString wxNotebook::GetPageText ( size_t nPage ) const
0e320a79 274{
f289196b
DW
275 BOOKTEXT vBookText;
276 wxChar zBuf[256];
277 wxString sStr;
278 ULONG ulRc;
0e320a79 279
90c0f5a9 280 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxEmptyString, wxT("notebook page out of range") );
0e320a79 281
f289196b
DW
282 memset(&vBookText, '\0', sizeof(BOOKTEXT));
283 vBookText.textLen = 0; // This will get the length
284 ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
285 ,BKM_QUERYTABTEXT
286 ,MPFROMLONG((ULONG)m_alPageId[nPage])
287 ,MPFROMP(&vBookText)
288 ));
9923c37d 289 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
f289196b 290 {
9923c37d 291 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS)
f289196b
DW
292 {
293 wxLogError(wxT("Invalid Page Id for page text querry."));
294 }
295 return wxEmptyString;
296 }
297 vBookText.textLen = ulRc + 1; // To get the null terminator
0fba44b4 298 vBookText.pString = (char*)zBuf;
f289196b
DW
299
300 //
301 // Now get the actual text
302 //
303 ulRc = LONGFROMMR(::WinSendMsg( m_hWnd
304 ,BKM_QUERYTABTEXT
305 ,MPFROMLONG((ULONG)m_alPageId[nPage])
306 ,MPFROMP(&vBookText)
307 ));
9923c37d 308 if (ulRc == (ULONG)BOOKERR_INVALID_PARAMETERS || ulRc == 0L)
f289196b
DW
309 {
310 return wxEmptyString;
311 }
312 if (ulRc > 255L)
313 ulRc = 255L;
314
315 vBookText.pString[ulRc] = '\0';
0fba44b4 316 sStr = (wxChar*)vBookText.pString;
f289196b
DW
317 return sStr;
318} // end of wxNotebook::GetPageText
319
6670f564 320int wxNotebook::GetPageImage ( size_t nPage ) const
0e320a79 321{
90c0f5a9 322 wxCHECK_MSG( IS_VALID_PAGE(nPage), wxNOT_FOUND, wxT("notebook page out of range") );
0e320a79 323
f289196b
DW
324 //
325 // For OS/2 just return the page
326 //
327 return nPage;
328} // end of wxNotebook::GetPageImage
0e320a79 329
f289196b 330bool wxNotebook::SetPageImage (
3979bf6b 331 size_t nPage
f289196b
DW
332, int nImage
333)
0e320a79 334{
0d598bae 335 wxBitmap vBitmap = (wxBitmap)m_imageList->GetBitmap(nImage);
0e320a79 336
f289196b
DW
337 return (bool)::WinSendMsg( GetHWND()
338 ,BKM_SETTABBITMAP
339 ,MPFROMLONG((ULONG)m_alPageId[nPage])
a4e15a8d 340 ,(MPARAM)wxCopyBmp(vBitmap.GetHBITMAP(), true)
f289196b
DW
341 );
342} // end of wxNotebook::SetPageImage
343
344void wxNotebook::SetImageList (
ab5ebf52 345 wxImageList* pImageList
f289196b 346)
cdf1e714 347{
6670f564 348 //
ab5ebf52
SN
349 // Does not really do anything yet, but at least we need to
350 // update the base class.
6670f564 351 //
ab5ebf52 352 wxNotebookBase::SetImageList(pImageList);
f289196b 353} // end of wxNotebook::SetImageList
cdf1e714 354
0e320a79 355// ----------------------------------------------------------------------------
f289196b 356// wxNotebook size settings
0e320a79 357// ----------------------------------------------------------------------------
f289196b
DW
358void wxNotebook::SetPageSize (
359 const wxSize& rSize
360)
0367c1c0 361{
52df30cf 362 SetSize(rSize);
f289196b
DW
363} // end of wxNotebook::SetPageSize
364
365void wxNotebook::SetPadding (
366 const wxSize& WXUNUSED(rPadding)
367)
0367c1c0 368{
f289196b
DW
369 //
370 // No padding in OS/2
371 //
372} // end of wxNotebook::SetPadding
373
374void wxNotebook::SetTabSize (
375 const wxSize& rSize
376)
377{
378 ::WinSendMsg( GetHWND()
379 ,BKM_SETDIMENSIONS
380 ,MPFROM2SHORT( (USHORT)rSize.x
381 ,(USHORT)rSize.y
382 )
383 ,(MPARAM)BKA_MAJORTAB
384 );
385} // end of wxNotebook::SetTabSize
386
387// ----------------------------------------------------------------------------
388// wxNotebook operations
389// ----------------------------------------------------------------------------
0367c1c0 390
f289196b
DW
391//
392// Remove one page from the notebook, without deleting
393//
6670f564 394wxNotebookPage* wxNotebook::DoRemovePage ( size_t nPage )
0e320a79 395{
6670f564 396 wxNotebookPage* pPageRemoved = wxNotebookBase::DoRemovePage(nPage);
0e320a79 397
f289196b
DW
398 if (!pPageRemoved)
399 return NULL;
0e320a79 400
f289196b
DW
401 ::WinSendMsg( GetHWND()
402 ,BKM_DELETEPAGE
403 ,MPFROMLONG((ULONG)m_alPageId[nPage])
404 ,(MPARAM)BKA_TAB
405 );
406 if (m_pages.IsEmpty())
407 {
408 //
409 // No selection any more, the notebook becamse empty
410 //
411 m_nSelection = -1;
412 }
413 else // notebook still not empty
414 {
415 //
416 // Change the selected page if it was deleted or became invalid
417 //
418 int nSelNew;
0e320a79 419
9923c37d 420 if (m_nSelection == (int)GetPageCount())
f289196b
DW
421 {
422 //
423 // Last page deleted, make the new last page the new selection
424 //
425 nSelNew = m_nSelection - 1;
426 }
9923c37d 427 else if (nPage <= (size_t)m_nSelection)
f289196b
DW
428 {
429 //
430 // We must show another page, even if it has the same index
431 //
432 nSelNew = m_nSelection;
433 }
434 else // nothing changes for the currently selected page
435 {
436 nSelNew = -1;
437
438 //
439 // We still must refresh the current page: this needs to be done
440 // for some unknown reason if the tab control shows the up-down
441 // control (i.e. when there are too many pages) -- otherwise after
442 // deleting a page nothing at all is shown
443 //
444 m_pages[m_nSelection]->Refresh();
445 }
0e320a79 446
f289196b
DW
447 if (nSelNew != -1)
448 {
449 //
450 // m_nSelection must be always valid so reset it before calling
451 // SetSelection()
452 //
453 m_nSelection = -1;
454 SetSelection(nSelNew);
455 }
456 }
457 return pPageRemoved;
458} // end of wxNotebook::DoRemovePage
0e320a79 459
f289196b
DW
460//
461// Remove all pages
462//
0e320a79
DW
463bool wxNotebook::DeleteAllPages()
464{
f289196b
DW
465 int nPageCount = GetPageCount();
466 int nPage;
467
468 for (nPage = 0; nPage < nPageCount; nPage++)
469 delete m_pages[nPage];
470 m_pages.Clear();
471 ::WinSendMsg( GetHWND()
472 ,BKM_DELETEPAGE
473 ,(MPARAM)0
474 ,(MPARAM)BKA_ALL
475 );
476 m_nSelection = -1;
6670f564
WS
477
478 return true;
f289196b
DW
479} // end of wxNotebook::DeleteAllPages
480
481//
482// Add a page to the notebook
483//
484bool wxNotebook::AddPage (
485 wxNotebookPage* pPage
486, const wxString& rStrText
487, bool bSelect
488, int nImageId
489)
0e320a79 490{
f289196b
DW
491 return InsertPage( GetPageCount()
492 ,pPage
493 ,rStrText
494 ,bSelect
495 ,nImageId
496 );
497} // end of wxNotebook::AddPage
498
499//
500// Same as AddPage() but does it at given position
501//
6670f564
WS
502bool wxNotebook::InsertPage ( size_t nPage,
503 wxNotebookPage* pPage,
504 const wxString& rsStrText,
505 bool bSelect,
506 int nImageId )
0e320a79 507{
f289196b
DW
508 ULONG ulApiPage;
509
0e320a79 510 wxASSERT( pPage != NULL );
90c0f5a9 511 wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), false );
0e320a79 512
f289196b
DW
513 //
514 // Under OS/2 we can only insert FIRST, LAST, NEXT or PREV. Requires
515 // two different calls to the API. Page 1 uses the BKA_FIRST. Subsequent
516 // pages use the previous page ID coupled with a BKA_NEXT call. Unlike
517 // Windows, OS/2 uses an internal Page ID to ID the pages.
518 //
519 // OS/2 also has a nice auto-size feature that automatically sizes the
520 // the attached window so we don't have to worry about the size of the
521 // window on the page.
522 //
523 if (nPage == 0)
524 {
525 ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
526 ,BKM_INSERTPAGE
527 ,(MPARAM)0
528 ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_FIRST)
529 ));
530 if (ulApiPage == 0L)
531 {
532 ERRORID vError;
533 wxString sError;
0e320a79 534
f289196b
DW
535 vError = ::WinGetLastError(vHabmain);
536 sError = wxPMErrorToStr(vError);
90c0f5a9 537 return false;
f289196b
DW
538 }
539 m_alPageId.Insert((long)ulApiPage, nPage);
540 }
541 else
542 {
543 ulApiPage = LONGFROMMR(::WinSendMsg( GetHWND()
544 ,BKM_INSERTPAGE
545 ,MPFROMLONG((ULONG)m_alPageId[nPage - 1])
546 ,MPFROM2SHORT(BKA_AUTOPAGESIZE | BKA_MAJOR, BKA_NEXT)
547 ));
548 if (ulApiPage == 0L)
549 {
550 ERRORID vError;
551 wxString sError;
0e320a79 552
f289196b
DW
553 vError = ::WinGetLastError(vHabmain);
554 sError = wxPMErrorToStr(vError);
90c0f5a9 555 return false;
f289196b
DW
556 }
557 m_alPageId.Insert((long)ulApiPage, nPage);
558 }
0e320a79 559
f289196b
DW
560 //
561 // Associate a window handle with the page
562 //
563 if (pPage)
564 {
565 if (!::WinSendMsg( GetHWND()
566 ,BKM_SETPAGEWINDOWHWND
567 ,MPFROMLONG((ULONG)m_alPageId[nPage])
568 ,MPFROMHWND(pPage->GetHWND())
569 ))
90c0f5a9 570 return false;
f289196b
DW
571 }
572 //
573 // If the inserted page is before the selected one, we must update the
574 // index of the selected page
575 //
9923c37d 576 if (nPage <= (size_t)m_nSelection)
f289196b
DW
577 {
578 //
579 // One extra page added
580 //
581 m_nSelection++;
582 }
0e320a79 583
f289196b
DW
584 if (pPage)
585 {
586 //
587 // Save the pointer to the page
588 //
589 m_pages.Insert( pPage
590 ,nPage
591 );
0e320a79
DW
592 }
593
f289196b
DW
594 //
595 // Now set TAB dimenstions
596 //
0e320a79 597
6670f564
WS
598 wxWindowDC vDC(this);
599 wxCoord nTextX;
600 wxCoord nTextY;
0e320a79 601
f289196b
DW
602 vDC.GetTextExtent(rsStrText, &nTextX, &nTextY);
603 nTextY *= 2;
9923c37d 604 nTextX = (wxCoord)(nTextX * 1.3);
f289196b
DW
605 if (nTextX > m_nTabSize)
606 {
607 m_nTabSize = nTextX;
608 ::WinSendMsg( GetHWND()
609 ,BKM_SETDIMENSIONS
610 ,MPFROM2SHORT((USHORT)m_nTabSize, (USHORT)nTextY)
611 ,(MPARAM)BKA_MAJORTAB
612 );
613 }
614 //
615 // Now set any TAB text
616 //
6670f564 617 if (!rsStrText.empty())
f289196b
DW
618 {
619 if (!SetPageText( nPage
620 ,rsStrText
621 ))
90c0f5a9 622 return false;
f289196b 623 }
0e320a79 624
f289196b
DW
625 //
626 // Now set any TAB bitmap image
627 //
628 if (nImageId != -1)
629 {
630 if (!SetPageImage( nPage
631 ,nImageId
632 ))
90c0f5a9 633 return false;
f289196b 634 }
7e99520b 635
f289196b
DW
636 if (pPage)
637 {
638 //
639 // Don't show pages by default (we'll need to adjust their size first)
640 //
90c0f5a9 641 HWND hWnd = GetWinHwnd(pPage);
f289196b
DW
642
643 WinSetWindowULong( hWnd
644 ,QWL_STYLE
645 ,WinQueryWindowULong( hWnd
646 ,QWL_STYLE
647 ) & ~WS_VISIBLE
648 );
649
650 //
651 // This updates internal flag too - otherwise it will get out of sync
652 //
90c0f5a9 653 pPage->Show(false);
0e320a79
DW
654 }
655
f289196b
DW
656 //
657 // Some page should be selected: either this one or the first one if there is
658 // still no selection
659 //
90c0f5a9 660 int nSelNew = -1;
f289196b
DW
661
662 if (bSelect)
663 nSelNew = nPage;
664 else if ( m_nSelection == -1 )
665 nSelNew = 0;
0e320a79 666
f289196b
DW
667 if (nSelNew != -1)
668 SetSelection(nSelNew);
52df30cf
SN
669
670 InvalidateBestSize();
671
90c0f5a9 672 return true;
f289196b
DW
673} // end of wxNotebook::InsertPage
674
675// ----------------------------------------------------------------------------
676// wxNotebook callbacks
677// ----------------------------------------------------------------------------
678void wxNotebook::OnSize(
679 wxSizeEvent& rEvent
680)
0e320a79 681{
f289196b
DW
682 rEvent.Skip();
683} // end of wxNotebook::OnSize
684
685void wxNotebook::OnSelChange (
686 wxNotebookEvent& rEvent
687)
688{
689 //
690 // Is it our tab control?
691 //
692 if (rEvent.GetEventObject() == this)
cdf1e714 693 {
90c0f5a9
WS
694 int nPageCount = GetPageCount();
695 int nSel;
696 ULONG ulOS2Sel = (ULONG)rEvent.GetOldSelection();
697 bool bFound = false;
fb46a9a6 698
1de4baa3 699 for (nSel = 0; nSel < nPageCount; nSel++)
f289196b 700 {
9923c37d 701 if (ulOS2Sel == (ULONG)m_alPageId[nSel])
1de4baa3 702 {
90c0f5a9 703 bFound = true;
1de4baa3
DW
704 break;
705 }
f289196b 706 }
f289196b 707
1de4baa3
DW
708 if (!bFound)
709 return;
710
90c0f5a9 711 m_pages[nSel]->Show(false);
1de4baa3
DW
712
713 ulOS2Sel = (ULONG)rEvent.GetSelection();
714
90c0f5a9 715 bFound = false;
1de4baa3
DW
716
717 for (nSel = 0; nSel < nPageCount; nSel++)
718 {
9923c37d 719 if (ulOS2Sel == (ULONG)m_alPageId[nSel])
1de4baa3 720 {
90c0f5a9 721 bFound = true;
1de4baa3
DW
722 break;
723 }
cdf1e714 724 }
1de4baa3
DW
725
726 if (!bFound)
727 return;
728
729 wxNotebookPage* pPage = m_pages[nSel];
730
90c0f5a9 731 pPage->Show(true);
f289196b
DW
732 m_nSelection = nSel;
733 }
fb46a9a6 734
f289196b
DW
735 //
736 // We want to give others a chance to process this message as well
737 //
738 rEvent.Skip();
739} // end of wxNotebook::OnSelChange
0e320a79 740
f289196b
DW
741void wxNotebook::OnSetFocus (
742 wxFocusEvent& rEvent
743)
0e320a79 744{
f289196b
DW
745 //
746 // This function is only called when the focus is explicitly set (i.e. from
747 // the program) to the notebook - in this case we don't need the
748 // complicated OnNavigationKey() logic because the programmer knows better
749 // what [s]he wants
750 //
0e320a79 751 // set focus to the currently selected page if any
f289196b
DW
752 //
753 if (m_nSelection != -1)
754 m_pages[m_nSelection]->SetFocus();
755 rEvent.Skip();
756} // end of wxNotebook::OnSetFocus
757
758void wxNotebook::OnNavigationKey (
759 wxNavigationKeyEvent& rEvent
760)
0e320a79 761{
f289196b
DW
762 if (rEvent.IsWindowChange())
763 {
764 //
765 // Change pages
766 //
767 AdvanceSelection(rEvent.GetDirection());
0e320a79 768 }
f289196b
DW
769 else
770 {
771 //
772 // We get this event in 2 cases
773 //
774 // a) one of our pages might have generated it because the user TABbed
775 // out from it in which case we should propagate the event upwards and
776 // our parent will take care of setting the focus to prev/next sibling
777 //
778 // or
779 //
780 // b) the parent panel wants to give the focus to us so that we
781 // forward it to our selected page. We can't deal with this in
782 // OnSetFocus() because we don't know which direction the focus came
783 // from in this case and so can't choose between setting the focus to
784 // first or last panel child
785 //
786 wxWindow* pParent = GetParent();
787
788 if (rEvent.GetEventObject() == pParent)
789 {
790 //
791 // No, it doesn't come from child, case (b): forward to a page
792 //
793 if (m_nSelection != -1)
794 {
795 //
796 // So that the page knows that the event comes from it's parent
797 // and is being propagated downwards
798 //
799 rEvent.SetEventObject(this);
800
801 wxWindow* pPage = m_pages[m_nSelection];
802
803 if (!pPage->GetEventHandler()->ProcessEvent(rEvent))
804 {
805 pPage->SetFocus();
806 }
807 //else: page manages focus inside it itself
808 }
809 else
810 {
811 //
812 // We have no pages - still have to give focus to _something_
813 //
814 SetFocus();
815 }
816 }
817 else
818 {
819 //
820 // It comes from our child, case (a), pass to the parent
821 //
822 if (pParent)
823 {
824 rEvent.SetCurrentFocus(this);
825 pParent->GetEventHandler()->ProcessEvent(rEvent);
826 }
0e320a79
DW
827 }
828 }
f289196b 829} // end of wxNotebook::OnNavigationKey
0e320a79
DW
830
831// ----------------------------------------------------------------------------
832// wxNotebook base class virtuals
833// ----------------------------------------------------------------------------
834
f289196b
DW
835//
836// Override these 2 functions to do nothing: everything is done in OnSize
837//
90c0f5a9 838void wxNotebook::SetConstraintSizes( bool WXUNUSED(bRecurse) )
0e320a79 839{
f289196b
DW
840 //
841 // Don't set the sizes of the pages - their correct size is not yet known
842 //
90c0f5a9 843 wxControl::SetConstraintSizes(false);
f289196b 844} // end of wxNotebook::SetConstraintSizes
0e320a79 845
90c0f5a9 846bool wxNotebook::DoPhase ( int WXUNUSED(nPhase) )
0e320a79 847{
90c0f5a9 848 return true;
f289196b 849} // end of wxNotebook::DoPhase
0e320a79 850
f289196b
DW
851// ----------------------------------------------------------------------------
852// wxNotebook Windows message handlers
853// ----------------------------------------------------------------------------
6670f564
WS
854bool wxNotebook::OS2OnScroll ( int nOrientation,
855 WXWORD wSBCode,
856 WXWORD wPos,
857 WXHWND wControl )
0e320a79 858{
f289196b
DW
859 //
860 // Don't generate EVT_SCROLLWIN events for the WM_SCROLLs coming from the
861 // up-down control
862 //
863 if (wControl)
90c0f5a9 864 return false;
f289196b
DW
865 return wxNotebookBase::OS2OnScroll( nOrientation
866 ,wSBCode
867 ,wPos
868 ,wControl
869 );
870} // end of wxNotebook::OS2OnScroll
0e320a79 871
f289196b 872#endif // wxUSE_NOTEBOOK