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