]> git.saurik.com Git - wxWidgets.git/blame - src/generic/notebook.cpp
render scrollbar's thumb as stippled bar to distinguish it from controls
[wxWidgets.git] / src / generic / notebook.cpp
CommitLineData
1e6d9499 1///////////////////////////////////////////////////////////////////////////////
7fc65a03
WS
2// Name: src/generic/notebook.cpp
3// Purpose: generic implementation of wxNotebook
1e6d9499
JS
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
65571936 9// Licence: wxWindows licence
1e6d9499
JS
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
ffecfa5a 19
1e6d9499
JS
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
df91131c 24 #pragma hdrstop
1e6d9499
JS
25#endif
26
bc5a5239
WS
27#if wxUSE_NOTEBOOK
28
df91131c
WS
29#include "wx/notebook.h"
30
31#ifndef WX_PRECOMP
32 #include "wx/string.h"
e4db172a 33 #include "wx/log.h"
ed4b0fdc 34 #include "wx/dcclient.h"
9eddec69 35 #include "wx/settings.h"
df91131c 36#endif
4055ed82 37
1c36c09c 38#include "wx/imaglist.h"
00dd3b18 39#include "wx/generic/tabg.h"
1e6d9499
JS
40
41// ----------------------------------------------------------------------------
42// macros
43// ----------------------------------------------------------------------------
44
45// check that the page index is valid
0ea23391 46#define IS_VALID_PAGE(nPage) ((nPage) < GetPageCount())
1e6d9499
JS
47
48// ----------------------------------------------------------------------------
49// event table
50// ----------------------------------------------------------------------------
51
2e4df4bf
VZ
52DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED)
53DEFINE_EVENT_TYPE(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING)
54
1e6d9499 55BEGIN_EVENT_TABLE(wxNotebook, wxControl)
ca65c044 56 EVT_NOTEBOOK_PAGE_CHANGED(wxID_ANY, wxNotebook::OnSelChange)
1e6d9499
JS
57 EVT_SIZE(wxNotebook::OnSize)
58 EVT_PAINT(wxNotebook::OnPaint)
59 EVT_MOUSE_EVENTS(wxNotebook::OnMouseEvent)
60 EVT_SET_FOCUS(wxNotebook::OnSetFocus)
61 EVT_NAVIGATION_KEY(wxNotebook::OnNavigationKey)
1e6d9499
JS
62END_EVENT_TABLE()
63
64IMPLEMENT_DYNAMIC_CLASS(wxNotebook, wxControl)
65IMPLEMENT_DYNAMIC_CLASS(wxNotebookEvent, wxCommandEvent)
1e6d9499
JS
66
67// ============================================================================
68// implementation
69// ============================================================================
70
00dd3b18
MB
71// ============================================================================
72// Private class
73// ============================================================================
74
dd5e8687
MW
75WX_DECLARE_HASH_MAP(int, wxNotebookPage*, wxIntegerHash, wxIntegerEqual,
76 wxIntToNotebookPageHashMap);
77
78WX_DECLARE_HASH_MAP(wxNotebookPage*, int, wxPointerHash, wxPointerEqual,
79 wxNotebookPageToIntHashMap);
80
00dd3b18
MB
81// This reuses wxTabView to draw the tabs.
82class WXDLLEXPORT wxNotebookTabView: public wxTabView
83{
84DECLARE_DYNAMIC_CLASS(wxNotebookTabView)
85public:
bc5a5239 86 wxNotebookTabView(wxNotebook* notebook, long style = wxTAB_STYLE_DRAW_BOX | wxTAB_STYLE_COLOUR_INTERIOR);
d3c7fc99 87 virtual ~wxNotebookTabView(void);
00dd3b18 88
bc5a5239
WS
89 // Called when a tab is activated
90 virtual void OnTabActivate(int activateId, int deactivateId);
91 // Allows vetoing
92 virtual bool OnTabPreActivate(int activateId, int deactivateId);
00dd3b18 93
dd5e8687
MW
94 // map integer ids used by wxTabView to wxNotebookPage pointers
95 int GetId(wxNotebookPage *page);
96 wxNotebookPage *GetPage(int id) { return m_idToPage[id]; }
97
00dd3b18 98protected:
dd5e8687
MW
99 wxNotebook* m_notebook;
100
101private:
102 wxIntToNotebookPageHashMap m_idToPage;
103 wxNotebookPageToIntHashMap m_pageToId;
104 int m_nextid;
00dd3b18
MB
105};
106
dd5e8687
MW
107static int GetPageId(wxTabView *tabview, wxNotebookPage *page)
108{
98b9b5ea 109 return wx_static_cast(wxNotebookTabView*, tabview)->GetId(page);
dd5e8687
MW
110}
111
1e6d9499
JS
112// ----------------------------------------------------------------------------
113// wxNotebook construction
114// ----------------------------------------------------------------------------
115
116// common part of all ctors
117void wxNotebook::Init()
118{
119 m_tabView = (wxNotebookTabView*) NULL;
1e6d9499
JS
120 m_nSelection = -1;
121}
122
123// default for dynamic class
124wxNotebook::wxNotebook()
125{
126 Init();
127}
128
129// the same arguments as for wxControl
130wxNotebook::wxNotebook(wxWindow *parent,
131 wxWindowID id,
132 const wxPoint& pos,
133 const wxSize& size,
134 long style,
135 const wxString& name)
136{
137 Init();
138
139 Create(parent, id, pos, size, style, name);
140}
141
142// Create() function
143bool wxNotebook::Create(wxWindow *parent,
144 wxWindowID id,
145 const wxPoint& pos,
146 const wxSize& size,
147 long style,
148 const wxString& name)
149{
150 // base init
151 SetName(name);
152
90f9b8ef
JS
153 if ( (style & wxBK_ALIGN_MASK) == wxBK_DEFAULT )
154 style |= wxBK_TOP;
6e271798 155
ca65c044 156 m_windowId = id == wxID_ANY ? NewControlId() : id;
1e6d9499 157
b4f8693c 158 if (!wxControl::Create(parent, id, pos, size, style|wxNO_BORDER, wxDefaultValidator, name))
ca65c044 159 return false;
1e6d9499 160
a756f210 161 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
f60d0f94 162
1e6d9499
JS
163 SetTabView(new wxNotebookTabView(this));
164
ca65c044 165 return true;
1e6d9499
JS
166}
167
168// dtor
169wxNotebook::~wxNotebook()
170{
171 delete m_tabView;
172}
173
174// ----------------------------------------------------------------------------
175// wxNotebook accessors
176// ----------------------------------------------------------------------------
1e6d9499
JS
177int wxNotebook::GetRowCount() const
178{
179 // TODO
180 return 0;
181}
182
15aad3b9 183int wxNotebook::SetSelection(size_t nPage)
1e6d9499 184{
1e6d9499
JS
185 wxASSERT( IS_VALID_PAGE(nPage) );
186
187 wxNotebookPage* pPage = GetPage(nPage);
188
dd5e8687 189 m_tabView->SetTabSelection(GetPageId(m_tabView, pPage));
3a5bcc4d 190
1e6d9499
JS
191 // TODO
192 return 0;
193}
194
6e271798
VZ
195int wxNotebook::ChangeSelection(size_t nPage)
196{
197 // FIXME: currently it does generate events too
198 return SetSelection(nPage);
199}
200
45f22d48 201#if 0
1e6d9499
JS
202void wxNotebook::AdvanceSelection(bool bForward)
203{
204 int nSel = GetSelection();
205 int nMax = GetPageCount() - 1;
206 if ( bForward )
207 SetSelection(nSel == nMax ? 0 : nSel + 1);
208 else
209 SetSelection(nSel == 0 ? nMax : nSel - 1);
210}
45f22d48 211#endif
1e6d9499 212
15aad3b9 213bool wxNotebook::SetPageText(size_t nPage, const wxString& strText)
1e6d9499
JS
214{
215 wxASSERT( IS_VALID_PAGE(nPage) );
3a5bcc4d 216
1e6d9499
JS
217 wxNotebookPage* page = GetPage(nPage);
218 if (page)
219 {
dd5e8687 220 m_tabView->SetTabText(GetPageId(m_tabView, page), strText);
1e6d9499 221 Refresh();
ca65c044 222 return true;
1e6d9499 223 }
3a5bcc4d 224
ca65c044 225 return false;
1e6d9499
JS
226}
227
15aad3b9 228wxString wxNotebook::GetPageText(size_t nPage) const
1e6d9499
JS
229{
230 wxASSERT( IS_VALID_PAGE(nPage) );
231
232 wxNotebookPage* page = ((wxNotebook*)this)->GetPage(nPage);
233 if (page)
dd5e8687 234 return m_tabView->GetTabText(GetPageId(m_tabView, page));
1e6d9499
JS
235 else
236 return wxEmptyString;
237}
238
3f9ee1cd 239int wxNotebook::GetPageImage(size_t WXUNUSED_UNLESS_DEBUG(nPage)) const
1e6d9499
JS
240{
241 wxASSERT( IS_VALID_PAGE(nPage) );
242
243 // TODO
244 return 0;
245}
246
3f9ee1cd
VZ
247bool wxNotebook::SetPageImage(size_t WXUNUSED_UNLESS_DEBUG(nPage),
248 int WXUNUSED(nImage))
1e6d9499
JS
249{
250 wxASSERT( IS_VALID_PAGE(nPage) );
251
252 // TODO
ca65c044 253 return false;
1e6d9499
JS
254}
255
9806a47c 256// set the size (the same for all pages)
7fc65a03 257void wxNotebook::SetPageSize(const wxSize& WXUNUSED(size))
9806a47c
JS
258{
259 // TODO
260}
261
262// set the padding between tabs (in pixels)
7fc65a03 263void wxNotebook::SetPadding(const wxSize& WXUNUSED(padding))
9806a47c
JS
264{
265 // TODO
266}
267
268// set the size of the tabs for wxNB_FIXEDWIDTH controls
7fc65a03 269void wxNotebook::SetTabSize(const wxSize& WXUNUSED(sz))
9806a47c
JS
270{
271 // TODO
272}
273
1e6d9499
JS
274// ----------------------------------------------------------------------------
275// wxNotebook operations
276// ----------------------------------------------------------------------------
277
278// remove one page from the notebook and delete it
15aad3b9 279bool wxNotebook::DeletePage(size_t nPage)
1e6d9499 280{
ca65c044 281 wxCHECK( IS_VALID_PAGE(nPage), false );
1e6d9499
JS
282
283 if (m_nSelection != -1)
284 {
ca65c044 285 m_pages[m_nSelection]->Show(false);
45f22d48 286 m_pages[m_nSelection]->Lower();
1e6d9499
JS
287 }
288
289 wxNotebookPage* pPage = GetPage(nPage);
3a5bcc4d 290
dd5e8687 291 m_tabView->RemoveTab(GetPageId(m_tabView, pPage));
1e6d9499 292
45f22d48
JS
293 m_pages.Remove(pPage);
294 delete pPage;
1e6d9499 295
45f22d48 296 if (m_pages.GetCount() == 0)
1e6d9499 297 {
bc5a5239
WS
298 m_nSelection = -1;
299 m_tabView->SetTabSelection(-1, false);
1e6d9499
JS
300 }
301 else if (m_nSelection > -1)
302 {
bc5a5239 303 m_nSelection = -1;
3a5bcc4d 304
dd5e8687 305 m_tabView->SetTabSelection(GetPageId(m_tabView, GetPage(0)), false);
3a5bcc4d 306
bc5a5239
WS
307 if (m_nSelection != 0)
308 ChangePage(-1, 0);
1e6d9499
JS
309 }
310
ca65c044 311 RefreshLayout(false);
1e6d9499 312
ca65c044 313 return true;
1e6d9499
JS
314}
315
316bool wxNotebook::DeletePage(wxNotebookPage* page)
317{
318 int pagePos = FindPagePosition(page);
319 if (pagePos > -1)
320 return DeletePage(pagePos);
321 else
ca65c044 322 return false;
1e6d9499
JS
323}
324
15aad3b9 325bool wxNotebook::RemovePage(size_t nPage)
64b090c7
MB
326{
327 return DoRemovePage(nPage) != NULL;
328}
329
330// remove one page from the notebook
331wxWindow* wxNotebook::DoRemovePage(size_t nPage)
1e6d9499 332{
10f2222c 333 wxCHECK( IS_VALID_PAGE(nPage), NULL );
1e6d9499 334
ca65c044 335 m_pages[nPage]->Show(false);
45f22d48 336 // m_pages[nPage]->Lower();
1e6d9499
JS
337
338 wxNotebookPage* pPage = GetPage(nPage);
3a5bcc4d 339
dd5e8687 340 m_tabView->RemoveTab(GetPageId(m_tabView, pPage));
1e6d9499 341
45f22d48 342 m_pages.Remove(pPage);
1e6d9499 343
45f22d48 344 if (m_pages.GetCount() == 0)
1e6d9499
JS
345 {
346 m_nSelection = -1;
ca65c044 347 m_tabView->SetTabSelection(-1, true);
1e6d9499
JS
348 }
349 else if (m_nSelection > -1)
350 {
351 // Only change the selection if the page we
352 // deleted was the selection.
30d2b71d 353 if (nPage == (size_t)m_nSelection)
1e6d9499
JS
354 {
355 m_nSelection = -1;
356 // Select the first tab. Generates a ChangePage.
ca65c044 357 m_tabView->SetTabSelection(0, true);
1e6d9499
JS
358 }
359 else
360 {
ca65c044 361 // We must adjust which tab we think is selected.
1e6d9499
JS
362 // If greater than the page we deleted, it must be moved down
363 // a notch.
30d2b71d 364 if (size_t(m_nSelection) > nPage)
1e6d9499
JS
365 m_nSelection -- ;
366 }
367 }
368
ca65c044 369 RefreshLayout(false);
1e6d9499 370
64b090c7 371 return pPage;
1e6d9499
JS
372}
373
374bool wxNotebook::RemovePage(wxNotebookPage* page)
375{
376 int pagePos = FindPagePosition(page);
377 if (pagePos > -1)
378 return RemovePage(pagePos);
379 else
ca65c044 380 return false;
1e6d9499
JS
381}
382
383// Find the position of the wxNotebookPage, -1 if not found.
384int wxNotebook::FindPagePosition(wxNotebookPage* page) const
385{
15aad3b9
VZ
386 size_t nPageCount = GetPageCount();
387 size_t nPage;
1e6d9499 388 for ( nPage = 0; nPage < nPageCount; nPage++ )
45f22d48 389 if (m_pages[nPage] == page)
1e6d9499
JS
390 return nPage;
391 return -1;
392}
393
394// remove all pages
395bool wxNotebook::DeleteAllPages()
396{
ca65c044 397 m_tabView->ClearTabs(true);
1e6d9499 398
15aad3b9
VZ
399 size_t nPageCount = GetPageCount();
400 size_t nPage;
1e6d9499 401 for ( nPage = 0; nPage < nPageCount; nPage++ )
45f22d48 402 delete m_pages[nPage];
1e6d9499 403
45f22d48 404 m_pages.Clear();
1e6d9499 405
ca65c044 406 return true;
1e6d9499
JS
407}
408
1e6d9499 409// same as AddPage() but does it at given position
15aad3b9 410bool wxNotebook::InsertPage(size_t nPage,
1e6d9499
JS
411 wxNotebookPage *pPage,
412 const wxString& strText,
413 bool bSelect,
7fc65a03 414 int WXUNUSED(imageId))
1e6d9499
JS
415{
416 wxASSERT( pPage != NULL );
ca65c044 417 wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), false );
1e6d9499 418
dd5e8687 419 m_tabView->AddTab(GetPageId(m_tabView, pPage), strText);
3a5bcc4d 420
1e6d9499 421 if (!bSelect)
ca65c044 422 pPage->Show(false);
1e6d9499
JS
423
424 // save the pointer to the page
45f22d48 425 m_pages.Insert(pPage, nPage);
1e6d9499
JS
426
427 if (bSelect)
428 {
429 // This will cause ChangePage to be called, via OnSelPage
3a5bcc4d 430
dd5e8687 431 m_tabView->SetTabSelection(GetPageId(m_tabView, pPage), true);
1e6d9499
JS
432 }
433
434 // some page must be selected: either this one or the first one if there is
435 // still no selection
436 if ( m_nSelection == -1 )
437 ChangePage(-1, 0);
438
ca65c044 439 RefreshLayout(false);
1e6d9499 440
ca65c044 441 return true;
1e6d9499
JS
442}
443
444// ----------------------------------------------------------------------------
445// wxNotebook callbacks
446// ----------------------------------------------------------------------------
447
448// @@@ OnSize() is used for setting the font when it's called for the first
449// time because doing it in ::Create() doesn't work (for unknown reasons)
450void wxNotebook::OnSize(wxSizeEvent& event)
451{
ca65c044 452 static bool s_bFirstTime = true;
1e6d9499
JS
453 if ( s_bFirstTime ) {
454 // TODO: any first-time-size processing.
ca65c044 455 s_bFirstTime = false;
1e6d9499
JS
456 }
457
458 RefreshLayout();
459
460 // Processing continues to next OnSize
461 event.Skip();
462}
463
464// This was supposed to cure the non-display of the notebook
465// until the user resizes the window.
466// What's going on?
5180055b 467void wxNotebook::OnInternalIdle()
1e6d9499 468{
5180055b
JS
469 wxWindow::OnInternalIdle();
470
ca65c044
WS
471#if 0
472 static bool s_bFirstTime = true;
1e6d9499
JS
473 if ( s_bFirstTime ) {
474 /*
475 wxSize sz(GetSize());
476 sz.x ++;
477 SetSize(sz);
478 sz.x --;
479 SetSize(sz);
480 */
481
482 /*
483 wxSize sz(GetSize());
484 wxSizeEvent sizeEvent(sz, GetId());
485 sizeEvent.SetEventObject(this);
486 GetEventHandler()->ProcessEvent(sizeEvent);
487 Refresh();
488 */
ca65c044 489 s_bFirstTime = false;
1e6d9499 490 }
5180055b 491#endif
1e6d9499
JS
492}
493
494// Implementation: calculate the layout of the view rect
495// and resize the children if required
496bool wxNotebook::RefreshLayout(bool force)
497{
498 if (m_tabView)
499 {
500 wxRect oldRect = m_tabView->GetViewRect();
501
502 int cw, ch;
503 GetClientSize(& cw, & ch);
504
505 int tabHeight = m_tabView->GetTotalTabHeight();
506 wxRect rect;
507 rect.x = 4;
508 rect.y = tabHeight + 4;
509 rect.width = cw - 8;
510 rect.height = ch - 4 - rect.y ;
2e4df4bf 511
1e6d9499
JS
512 m_tabView->SetViewRect(rect);
513
25889d3c 514 m_tabView->LayoutTabs();
1e6d9499
JS
515
516 // Need to do it a 2nd time to get the tab height with
517 // the new view width, since changing the view width changes the
518 // tab layout.
519 tabHeight = m_tabView->GetTotalTabHeight();
520 rect.x = 4;
521 rect.y = tabHeight + 4;
522 rect.width = cw - 8;
523 rect.height = ch - 4 - rect.y ;
2e4df4bf 524
1e6d9499
JS
525 m_tabView->SetViewRect(rect);
526
25889d3c 527 m_tabView->LayoutTabs();
1e6d9499
JS
528
529 if (!force && (rect == oldRect))
ca65c044 530 return false;
1e6d9499
JS
531
532 // fit the notebook page to the tab control's display area
533
15aad3b9
VZ
534 size_t nCount = m_pages.Count();
535 for ( size_t nPage = 0; nPage < nCount; nPage++ ) {
45f22d48 536 wxNotebookPage *pPage = m_pages[nPage];
10d1f413 537 wxRect clientRect = GetAvailableClientSize();
1e6d9499
JS
538 if (pPage->IsShown())
539 {
1e6d9499
JS
540 pPage->SetSize(clientRect.x, clientRect.y, clientRect.width, clientRect.height);
541 if ( pPage->GetAutoLayout() )
542 pPage->Layout();
543 }
544 }
545 Refresh();
546 }
ca65c044 547 return true;
1e6d9499
JS
548}
549
550void wxNotebook::OnSelChange(wxNotebookEvent& event)
551{
552 // is it our tab control?
553 if ( event.GetEventObject() == this )
554 {
555 if (event.GetSelection() != m_nSelection)
556 ChangePage(event.GetOldSelection(), event.GetSelection());
557 }
558
559 // we want to give others a chance to process this message as well
560 event.Skip();
561}
562
563void wxNotebook::OnSetFocus(wxFocusEvent& event)
564{
565 // set focus to the currently selected page if any
566 if ( m_nSelection != -1 )
45f22d48 567 m_pages[m_nSelection]->SetFocus();
1e6d9499
JS
568
569 event.Skip();
570}
571
572void wxNotebook::OnNavigationKey(wxNavigationKeyEvent& event)
573{
574 if ( event.IsWindowChange() ) {
575 // change pages
576 AdvanceSelection(event.GetDirection());
577 }
578 else {
579 // pass to the parent
580 if ( GetParent() ) {
581 event.SetCurrentFocus(this);
582 GetParent()->ProcessEvent(event);
583 }
584 }
585}
586
587// ----------------------------------------------------------------------------
588// wxNotebook base class virtuals
589// ----------------------------------------------------------------------------
590
591// override these 2 functions to do nothing: everything is done in OnSize
592
593void wxNotebook::SetConstraintSizes(bool /* recurse */)
594{
595 // don't set the sizes of the pages - their correct size is not yet known
ca65c044 596 wxControl::SetConstraintSizes(false);
1e6d9499
JS
597}
598
599bool wxNotebook::DoPhase(int /* nPhase */)
600{
ca65c044 601 return true;
1e6d9499
JS
602}
603
af111fc3 604void wxNotebook::Command(wxCommandEvent& WXUNUSED(event))
1e6d9499 605{
b0c0a393 606 wxFAIL_MSG(wxT("wxNotebook::Command not implemented"));
1e6d9499
JS
607}
608
609// ----------------------------------------------------------------------------
610// wxNotebook helper functions
611// ----------------------------------------------------------------------------
612
613// hide the currently active panel and show the new one
614void wxNotebook::ChangePage(int nOldSel, int nSel)
615{
616 // cout << "ChangePage: " << nOldSel << ", " << nSel << "\n";
617 wxASSERT( nOldSel != nSel ); // impossible
618
619 if ( nOldSel != -1 ) {
ca65c044 620 m_pages[nOldSel]->Show(false);
45f22d48 621 m_pages[nOldSel]->Lower();
1e6d9499
JS
622 }
623
45f22d48 624 wxNotebookPage *pPage = m_pages[nSel];
1e6d9499
JS
625
626 wxRect clientRect = GetAvailableClientSize();
627 pPage->SetSize(clientRect.x, clientRect.y, clientRect.width, clientRect.height);
628
f6bcfd97
BP
629 Refresh();
630
ca65c044 631 pPage->Show(true);
1e6d9499
JS
632 pPage->Raise();
633 pPage->SetFocus();
634
1e6d9499
JS
635 m_nSelection = nSel;
636}
637
638void wxNotebook::OnMouseEvent(wxMouseEvent& event)
639{
640 if (m_tabView)
641 m_tabView->OnEvent(event);
642}
643
644void wxNotebook::OnPaint(wxPaintEvent& WXUNUSED(event) )
645{
646 wxPaintDC dc(this);
647 if (m_tabView)
648 m_tabView->Draw(dc);
649}
650
6bae6726
MB
651wxSize wxNotebook::CalcSizeFromPage(const wxSize& sizePage) const
652{
653 // MBN: since the total tab height is really a function of the
654 // width, this should really call
655 // GetTotalTabHeightPretendingWidthIs(), but the current
656 // implementation will suffice, provided the wxNotebook has been
657 // created with a sensible initial width.
658 return wxSize( sizePage.x + 12,
659 sizePage.y + m_tabView->GetTotalTabHeight() + 6 + 4 );
660}
661
1e6d9499
JS
662wxRect wxNotebook::GetAvailableClientSize()
663{
664 int cw, ch;
665 GetClientSize(& cw, & ch);
666
667 int tabHeight = m_tabView->GetTotalTabHeight();
668
669 // TODO: these margins should be configurable.
670 wxRect rect;
671 rect.x = 6;
672 rect.y = tabHeight + 6;
673 rect.width = cw - 12;
674 rect.height = ch - 4 - rect.y ;
675
676 return rect;
677}
678
679/*
680 * wxNotebookTabView
681 */
2e4df4bf 682
1e6d9499
JS
683IMPLEMENT_CLASS(wxNotebookTabView, wxTabView)
684
dd5e8687
MW
685wxNotebookTabView::wxNotebookTabView(wxNotebook *notebook, long style)
686 : wxTabView(style), m_nextid(1)
1e6d9499
JS
687{
688 m_notebook = notebook;
689
690 m_notebook->SetTabView(this);
691
692 SetWindow(m_notebook);
693}
694
695wxNotebookTabView::~wxNotebookTabView(void)
696{
697}
698
dd5e8687
MW
699int wxNotebookTabView::GetId(wxNotebookPage *page)
700{
701 int& id = m_pageToId[page];
702
703 if (!id)
704 {
705 id = m_nextid++;
706 m_idToPage[id] = page;
707 }
708
709 return id;
710}
711
1e6d9499
JS
712// Called when a tab is activated
713void wxNotebookTabView::OnTabActivate(int activateId, int deactivateId)
714{
715 if (!m_notebook)
716 return;
717
718 wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, m_notebook->GetId());
719
720 // Translate from wxTabView's ids (which aren't position-dependent)
721 // to wxNotebook's (which are).
dd5e8687
MW
722 wxNotebookPage* pActive = GetPage(activateId);
723 wxNotebookPage* pDeactive = GetPage(deactivateId);
1e6d9499
JS
724
725 int activatePos = m_notebook->FindPagePosition(pActive);
726 int deactivatePos = m_notebook->FindPagePosition(pDeactive);
727
728 event.SetEventObject(m_notebook);
729 event.SetSelection(activatePos);
730 event.SetOldSelection(deactivatePos);
731 m_notebook->GetEventHandler()->ProcessEvent(event);
732}
733
1c507b17
JS
734// Allows Vetoing
735bool wxNotebookTabView::OnTabPreActivate(int activateId, int deactivateId)
736{
ca65c044
WS
737 bool retval = true;
738
1c507b17
JS
739 if (m_notebook)
740 {
741 wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGING, m_notebook->GetId());
742
1c507b17
JS
743 // Translate from wxTabView's ids (which aren't position-dependent)
744 // to wxNotebook's (which are).
dd5e8687
MW
745 wxNotebookPage* pActive = GetPage(activateId);
746 wxNotebookPage* pDeactive = GetPage(deactivateId);
1c507b17
JS
747
748 int activatePos = m_notebook->FindPagePosition(pActive);
749 int deactivatePos = m_notebook->FindPagePosition(pDeactive);
750
1c507b17
JS
751 event.SetEventObject(m_notebook);
752 event.SetSelection(activatePos);
753 event.SetOldSelection(deactivatePos);
754 if (m_notebook->GetEventHandler()->ProcessEvent(event))
755 {
756 retval = event.IsAllowed();
757 }
758 }
759 return retval;
ca65c044 760}
bc5a5239
WS
761
762#endif // wxUSE_NOTEBOOK