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