]> git.saurik.com Git - wxWidgets.git/blame - src/generic/treebkg.cpp
refactored wxGTK scrolling: it has now fully-functioning wxScrollHelper and a lot...
[wxWidgets.git] / src / generic / treebkg.cpp
CommitLineData
eca15c0d
VZ
1///////////////////////////////////////////////////////////////////////////////
2// Name: src/generic/treebkg.cpp
3// Purpose: generic implementation of wxTreebook
4// Author: Evgeniy Tarassov, Vadim Zeitlin
5// Modified by:
6// Created: 2005-09-15
7// RCS-ID: $Id$
8// Copyright: (c) 2005 Vadim Zeitlin <vadim@wxwidgets.org>
9// Licence: wxWindows licence
10///////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27#if wxUSE_TREEBOOK
28
29#include "wx/treebook.h"
30#include "wx/imaglist.h"
31#include "wx/settings.h"
32
33// ----------------------------------------------------------------------------
34// various wxWidgets macros
35// ----------------------------------------------------------------------------
36
37// check that the page index is valid
38#define IS_VALID_PAGE(nPage) ((nPage) < DoInternalGetPageCount())
39
40// ----------------------------------------------------------------------------
41// event table
42// ----------------------------------------------------------------------------
43
44IMPLEMENT_DYNAMIC_CLASS(wxTreebook, wxControl)
45IMPLEMENT_DYNAMIC_CLASS(wxTreebookEvent, wxNotifyEvent)
46
47const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING = wxNewEventType();
48const wxEventType wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED = wxNewEventType();
49const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED = wxNewEventType();
50const wxEventType wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED = wxNewEventType();
51const int wxID_TREEBOOKTREEVIEW = wxNewId();
52
53BEGIN_EVENT_TABLE(wxTreebook, wxBookCtrlBase)
54 EVT_SIZE(wxTreebook::OnSize)
55 EVT_TREE_SEL_CHANGED (wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeSelectionChange)
56 EVT_TREE_ITEM_EXPANDED (wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeNodeExpandedCollapsed)
57 EVT_TREE_ITEM_COLLAPSED(wxID_TREEBOOKTREEVIEW, wxTreebook::OnTreeNodeExpandedCollapsed)
58END_EVENT_TABLE()
59
60// ============================================================================
61// wxTreebook implementation
62// ============================================================================
63
64// ----------------------------------------------------------------------------
65// wxTreebook creation
66// ----------------------------------------------------------------------------
67
68void wxTreebook::Init()
69{
70 m_tree = NULL;
71 m_selection =
72 m_actualSelection = wxNOT_FOUND;
73}
74
75bool
76wxTreebook::Create(wxWindow *parent,
77 wxWindowID id,
78 const wxPoint& pos,
79 const wxSize& size,
80 long style,
81 const wxString& name)
82{
83 // Check the style flag to have either wxTBK_RIGHT or wxTBK_LEFT
84 if ( style & wxTBK_RIGHT )
85 {
86 wxASSERT_MSG( !(style & wxTBK_LEFT),
87 _T("RIGHT and LEFT can't be used together") );
88 }
89 else
90 {
91 style |= wxTBK_LEFT;
92 }
93
94 // no border for this control, it doesn't look nice together with the tree
95 style &= ~wxBORDER_MASK;
96 style |= wxBORDER_NONE;
97
98 if ( !wxControl::Create(parent, id, pos, size,
99 style, wxDefaultValidator, name) )
100 return false;
101
102 m_tree = new wxTreeCtrl
103 (
104 this,
105 wxID_TREEBOOKTREEVIEW,
106 wxDefaultPosition,
107 wxDefaultSize,
108 wxBORDER_SIMPLE |
109 wxTR_HAS_BUTTONS |
110 wxTR_HIDE_ROOT |
111 wxTR_LINES_AT_ROOT |
112 wxTR_SINGLE
113 );
114 m_tree->AddRoot(wxEmptyString); // label doesn't matter, it's hidden
115
116#ifdef __WXMSW__
117 // see listbook.h for origins of that
118 // On XP with themes enabled the GetViewRect used in GetListSize to
119 // determine the space needed for the list view will incorrectly return
120 // (0,0,0,0) the first time. So send a pending event so OnSize will be
121 // called again after the window is ready to go. Technically we don't
122 // need to do this on non-XP windows, but if things are already sized
123 // correctly then nothing changes and so there is no harm.
124 wxSizeEvent evt;
125 GetEventHandler()->AddPendingEvent(evt);
126#endif
127
128 return true;
129}
130
131
132// insert a new page just before the pagePos
133bool wxTreebook::InsertPage(size_t pagePos,
134 wxWindow *page,
135 const wxString& text,
136 bool bSelect,
137 int imageId)
138{
139 return DoInsertPage(pagePos, page, text, bSelect, imageId);
140}
141
142bool wxTreebook::AddSubPage(size_t pagePos,
143 wxWindow *page,
144 const wxString& text,
145 bool bSelect,
146 int imageId)
147{
148 return DoInsertSubPage(pagePos, page, text, bSelect, imageId);
149}
150
151bool wxTreebook::AddPage(wxWindow *page, const wxString& text, bool bSelect,
152 int imageId)
153{
154 return DoInsertPage(m_treeIds.GetCount(), page, text, bSelect, imageId);
155}
156
157// insertion time is linear to the number of top-pages
158bool wxTreebook::AddSubPage(wxWindow *page, const wxString& text, bool bSelect, int imageId)
159{
160 return DoAddSubPage(page, text, bSelect, imageId);
161}
162
163
164bool wxTreebook::DoInsertPage(size_t pagePos,
165 wxWindow *page,
166 const wxString& text,
167 bool bSelect,
168 int imageId)
169{
170 wxCHECK_MSG( pagePos <= DoInternalGetPageCount(), false,
171 wxT("Invalid treebook page position") );
172
173 if ( !wxBookCtrlBase::InsertPage(pagePos, page, text, bSelect, imageId) )
174 return false;
175
176 wxTreeItemId newId;
177 if ( pagePos == DoInternalGetPageCount() )
178 {
179 // append the page to the end
180 wxTreeItemId rootId = m_tree->GetRootItem();
181
182 newId = m_tree->AppendItem(rootId, text, imageId);
183 }
184 else // insert the new page before the given one
185 {
186 wxTreeItemId nodeId = m_treeIds[pagePos];
187
188 wxTreeItemId previousId = m_tree->GetPrevSibling(nodeId);
189 wxTreeItemId parentId = m_tree->GetItemParent(nodeId);
190
191 if ( previousId.IsOk() )
192 {
193 // insert before the sibling - previousId
194 newId = m_tree->InsertItem(parentId, previousId, text, imageId);
195 }
196 else // no prev siblings -- insert as a first child
197 {
198 wxASSERT_MSG( parentId.IsOk(), wxT( "Tree has no root node?" ) );
199
200 newId = m_tree->PrependItem(parentId, text, imageId);
201 }
202 }
203
204 if ( !newId.IsOk() )
205 {
206 //something wrong -> cleaning and returning with false
207 (void)wxBookCtrlBase::DoRemovePage(pagePos);
208
209 wxFAIL_MSG( wxT("Failed to insert treebook page") );
210 return false;
211 }
212
213 DoInternalAddPage(pagePos, page, newId);
214
215 DoUpdateSelection(bSelect, pagePos);
216
217 return true;
218}
219
220bool wxTreebook::DoAddSubPage(wxWindow *page, const wxString& text, bool bSelect, int imageId)
221{
222 wxTreeItemId rootId = m_tree->GetRootItem();
223
224 wxTreeItemId lastNodeId = m_tree->GetLastChild(rootId);
225
226 wxCHECK_MSG( lastNodeId.IsOk(), false,
227 _T("Can't insert sub page when there are no pages") );
228
229 // now calculate its position (should we save/update it too?)
230 size_t newPos = m_tree->GetCount() -
231 (m_tree->GetChildrenCount(lastNodeId, true) + 1);
232
233 return DoInsertSubPage(newPos, page, text, bSelect, imageId);
234}
235
236bool wxTreebook::DoInsertSubPage(size_t pagePos,
237 wxTreebookPage *page,
238 const wxString& text,
239 bool bSelect,
240 int imageId)
241{
242 wxTreeItemId parentId = DoInternalGetPage(pagePos);
243 wxCHECK_MSG( parentId.IsOk(), false, wxT("invalid tree item") );
244
245 size_t newPos = pagePos + m_tree->GetChildrenCount(parentId, true) + 1;
246 wxASSERT_MSG( newPos <= DoInternalGetPageCount(),
247 wxT("Internal error in tree insert point calculation") );
248
249 if ( !wxBookCtrlBase::InsertPage(newPos, page, text, bSelect, imageId) )
250 return false;
251
252 wxTreeItemId newId = m_tree->AppendItem(parentId, text, imageId);
253
254 if ( !newId.IsOk() )
255 {
256 (void)wxBookCtrlBase::DoRemovePage(newPos);
257
258 wxFAIL_MSG( wxT("Failed to insert treebook page") );
259 return false;
260 }
261
262 DoInternalAddPage(newPos, page, newId);
263
264 DoUpdateSelection(bSelect, newPos);
265
266 return true;
267}
268
269bool wxTreebook::DeletePage(size_t pagePos)
270{
271 wxCHECK_MSG( IS_VALID_PAGE(pagePos), false, wxT("Invalid tree index") );
272
273 wxTreebookPage *oldPage = DoRemovePage(pagePos);
274 if ( !oldPage )
275 return false;
276
277 delete oldPage;
278
279 return true;
280}
281
282wxTreebookPage *wxTreebook::DoRemovePage(size_t pagePos)
283{
284 wxTreeItemId pageId = DoInternalGetPage(pagePos);
285 wxCHECK_MSG( pageId.IsOk(), NULL, wxT("Invalid tree index") );
286
287 wxTreebookPage * oldPage = GetPage(pagePos);
288
289 size_t subCount = m_tree->GetChildrenCount(pageId, true);
290 wxASSERT_MSG ( IS_VALID_PAGE(pagePos + subCount),
291 wxT("Internal error in wxTreebook::DoRemovePage") );
292
293 // here we are going to delete ALL the pages in the range
294 // [pagePos, pagePos + subCount] -- the page and its children
295
296 // deleting all the pages from the base class
297 for ( size_t i = 0; i <= subCount; ++i )
298 {
299 wxTreebookPage *page = wxBookCtrlBase::DoRemovePage(pagePos);
300
301 // don't delete the page itself though -- it will be deleted in
302 // DeletePage() when we return
303 if ( i )
304 {
305 delete page;
306 }
307 }
308
309 DoInternalRemovePageRange(pagePos, subCount);
310
311 m_tree->DeleteChildren( pageId );
312 m_tree->Delete( pageId );
313
314 return oldPage;
315}
316
317bool wxTreebook::DeleteAllPages()
318{
319 wxBookCtrlBase::DeleteAllPages();
320 m_treeIds.Clear();
321 m_selection =
322 m_actualSelection = wxNOT_FOUND;
323
324 m_tree->DeleteChildren(m_tree->GetRootItem());
325
326 return true;
327}
328
329void wxTreebook::DoInternalAddPage(size_t newPos,
330 wxTreebookPage *page,
331 wxTreeItemId pageId)
332{
333 wxASSERT_MSG( newPos <= m_treeIds.GetCount(), wxT("Ivalid index passed to wxTreebook::DoInternalAddPage") );
334
335 // hide newly inserted page initially (it will be shown when selected)
336 if ( page )
337 page->Hide();
338
339 if ( newPos == m_treeIds.GetCount() )
340 {
341 // append
342 m_treeIds.Add(pageId);
343 }
344 else // insert
345 {
346 m_treeIds.Insert(pageId, newPos);
347
348 if ( m_selection != wxNOT_FOUND && newPos <= (size_t)m_selection )
349 {
350 // selection has been moved one unit toward the end
351 ++m_selection;
352 if ( m_actualSelection != wxNOT_FOUND )
353 ++m_actualSelection;
354 }
355 else if ( m_actualSelection != wxNOT_FOUND &&
356 newPos <= (size_t)m_actualSelection )
357 {
358 DoSetSelection(m_selection);
359 }
360 }
361}
362
363void wxTreebook::DoInternalRemovePageRange(size_t pagePos, size_t subCount)
364{
365 // Attention: this function is only for a situation when we delete a node
366 // with all its children so pagePos is the node's index and subCount is the
367 // node children count
368 wxASSERT_MSG( pagePos + subCount < m_treeIds.GetCount(),
369 wxT("Ivalid page index") );
370
371 wxTreeItemId pageId = m_treeIds[pagePos];
372
373 m_treeIds.RemoveAt(pagePos, subCount + 1);
374
375 if ( m_selection != wxNOT_FOUND )
376 {
377 if ( (size_t)m_selection > pagePos + subCount)
378 {
379 // selection is far after the deleted page, so just update the index and move on
380 m_selection -= 1 + subCount;
381 if ( m_actualSelection != wxNOT_FOUND)
382 {
383 m_actualSelection -= subCount + 1;
384 }
385 }
386 else if ( (size_t)m_selection >= pagePos )
387 {
388 // as selected page is going to be deleted, try to select the next
389 // sibling if exists, if not then the parent
390 wxTreeItemId nodeId = m_tree->GetNextSibling(pageId);
391
392 m_selection = wxNOT_FOUND;
393 m_actualSelection = wxNOT_FOUND;
394
395 if ( nodeId.IsOk() )
396 {
397 // selecting next siblings
398 m_tree->SelectItem(nodeId);
399 }
400 else // no next sibling, select the parent
401 {
402 wxTreeItemId parentId = m_tree->GetItemParent(pageId);
403
404 if ( parentId.IsOk() && parentId != m_tree->GetRootItem() )
405 {
406 m_tree->SelectItem(parentId);
407 }
408 else // parent is root
409 {
410 // we can't select it as it's hidden
411 DoUpdateSelection(false, wxNOT_FOUND);
412 }
413 }
414 }
415 else if ( m_actualSelection != wxNOT_FOUND &&
416 (size_t)m_actualSelection >= pagePos )
417 {
418 // nothing to do -- selection is before the deleted node, but
419 // actually shown page (the first (sub)child with page != NULL) is
420 // already deleted
421 m_actualSelection = m_selection;
422 DoSetSelection(m_selection);
423 }
424 //else: nothing to do -- selection is before the deleted node
425 }
426 else
427 {
428 DoUpdateSelection(false, wxNOT_FOUND);
429 }
430}
431
432
433void wxTreebook::DoUpdateSelection(bool bSelect, int newPos)
434{
435 int newSelPos;
436 if ( bSelect )
437 {
438 newSelPos = newPos;
439 }
440 else if ( m_selection == wxNOT_FOUND && DoInternalGetPageCount() > 0 )
441 {
442 newSelPos = 0;
443 }
444 else
445 {
446 newSelPos = wxNOT_FOUND;
447 }
448
449 if ( newSelPos != wxNOT_FOUND )
450 {
451 SetSelection((size_t)newSelPos);
452 }
453}
454
455wxTreeItemId wxTreebook::DoInternalGetPage(size_t pagePos) const
456{
457 if ( pagePos >= m_treeIds.GetCount() )
458 {
459 // invalid position but ok here, in this internal function, don't assert
460 // (the caller will do it)
461 return wxTreeItemId();
462 }
463
464 return m_treeIds[pagePos];
465}
466
467int wxTreebook::DoInternalFindPageById(wxTreeItemId pageId) const
468{
469 const size_t count = m_treeIds.GetCount();
470 for ( size_t i = 0; i < count; ++i )
471 {
472 if ( m_treeIds[i] == pageId )
473 return i;
474 }
475
476 return wxNOT_FOUND;
477}
478
479bool wxTreebook::IsNodeExpanded(size_t pagePos) const
480{
481 wxTreeItemId pageId = DoInternalGetPage(pagePos);
482
483 wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
484
485 return m_tree->IsExpanded(pageId);
486}
487
488bool wxTreebook::ExpandNode(size_t pagePos, bool expand)
489{
490 wxTreeItemId pageId = DoInternalGetPage(pagePos);
491
492 wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
493
494 if ( expand )
495 {
496 m_tree->Expand( pageId );
497 }
498 else // collapse
499 {
500 m_tree->Collapse( pageId );
501
502 // rely on the events generated by wxTreeCtrl to update selection
503 }
504
505 return true;
506}
507
508int wxTreebook::GetPageParent(size_t pagePos) const
509{
510 wxTreeItemId nodeId = DoInternalGetPage( pagePos );
511 wxCHECK_MSG( nodeId.IsOk(), wxNOT_FOUND, wxT("Invalid page index spacified!") );
512
513 const wxTreeItemId parent = m_tree->GetItemParent( nodeId );
514
515 return parent.IsOk() ? DoInternalFindPageById(parent) : wxNOT_FOUND;
516}
517
518bool wxTreebook::SetPageText(size_t n, const wxString& strText)
519{
520 wxTreeItemId pageId = DoInternalGetPage(n);
521
522 wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
523
524 m_tree->SetItemText(pageId, strText);
525
526 return true;
527}
528
529wxString wxTreebook::GetPageText(size_t n) const
530{
531 wxTreeItemId pageId = DoInternalGetPage(n);
532
533 wxCHECK_MSG( pageId.IsOk(), wxString(), wxT("invalid tree item") );
534
535 return m_tree->GetItemText(pageId);
536}
537
538int wxTreebook::GetPageImage(size_t n) const
539{
540 wxTreeItemId pageId = DoInternalGetPage(n);
541
542 wxCHECK_MSG( pageId.IsOk(), wxNOT_FOUND, wxT("invalid tree item") );
543
544 return m_tree->GetItemImage(pageId);
545}
546
547bool wxTreebook::SetPageImage(size_t n, int imageId)
548{
549 wxTreeItemId pageId = DoInternalGetPage(n);
550
551 wxCHECK_MSG( pageId.IsOk(), false, wxT("invalid tree item") );
552
553 m_tree->SetItemImage(pageId, imageId);
554
555 return true;
556}
557
558wxSize wxTreebook::CalcSizeFromPage(const wxSize& sizePage) const
559{
560 const wxSize sizeTree = GetTreeSize();
561
562 wxSize size = sizePage;
563 size.x += sizeTree.x;
564
565 return size;
566}
567
568int wxTreebook::GetSelection() const
569{
570 return m_selection;
571}
572
573int wxTreebook::SetSelection(size_t pagePos)
574{
575 if ( (size_t)m_selection != pagePos )
576 return DoSetSelection(pagePos);
577
578 return m_selection;
579}
580
581int wxTreebook::DoSetSelection(size_t pagePos)
582{
583 wxCHECK_MSG( IS_VALID_PAGE(pagePos), wxNOT_FOUND,
584 wxT("invalid page index in wxListbook::SetSelection()") );
585 wxASSERT_MSG( GetPageCount() == DoInternalGetPageCount(),
586 wxT("wxTreebook logic error: m_treeIds and m_pages not in sync!"));
587
588 const int oldSel = m_selection;
589
590 wxTreebookEvent event(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGING, m_windowId);
591 event.SetEventObject(this);
592 event.SetSelection(pagePos);
593 event.SetOldSelection(m_selection);
594
595 // don't send the event if the old and new pages are the same; do send it
596 // otherwise and be prepared for it to be vetoed
597 if ( (int)pagePos == m_selection ||
598 !GetEventHandler()->ProcessEvent(event) ||
599 event.IsAllowed() )
600 {
601 // hide the previously shown page
602 wxTreebookPage * const oldPage = DoGetCurrentPage();
603 if ( oldPage )
604 oldPage->Hide();
605
606 // then show the new one
607 m_selection = pagePos;
608 wxTreebookPage *page = wxBookCtrlBase::GetPage(m_selection);
609 if ( !page )
610 {
611 // find the next page suitable to be shown: the first (grand)child
612 // of this one with a non-NULL associated page
613 wxTreeItemId childId = m_treeIds[pagePos];
614 m_actualSelection = pagePos;
615 while ( !page && childId.IsOk() )
616 {
617 wxTreeItemIdValue cookie;
618 childId = m_tree->GetFirstChild( childId, cookie );
619 if ( childId.IsOk() )
620 {
621 page = wxBookCtrlBase::GetPage(++m_actualSelection);
622 }
623 }
624
625 wxASSERT_MSG( page, wxT("no page to show found!") );
626 }
627
628 if ( page )
629 {
630 page->SetSize(GetPageRect());
631 page->Show();
632 }
633
634 m_tree->SelectItem(DoInternalGetPage(pagePos));
635
636 // notify about the (now completed) page change
637 event.SetEventType(wxEVT_COMMAND_TREEBOOK_PAGE_CHANGED);
638 (void)GetEventHandler()->ProcessEvent(event);
639 }
640 else // page change vetoed
641 {
642 // tree selection might have already had changed
643 m_tree->SelectItem(DoInternalGetPage(oldSel));
644 }
645
646 return oldSel;
647}
648
649void wxTreebook::SetImageList(wxImageList *imageList)
650{
651 wxBookCtrlBase::SetImageList(imageList);
652 m_tree->SetImageList(imageList);
653}
654
655void wxTreebook::AssignImageList(wxImageList *imageList)
656{
657 wxBookCtrlBase::AssignImageList(imageList);
658 m_tree->SetImageList(imageList);
659}
660
661// ----------------------------------------------------------------------------
662// event handlers
663// ----------------------------------------------------------------------------
664
665void wxTreebook::OnTreeSelectionChange(wxTreeEvent& event)
666{
667 wxTreeItemId newId = event.GetItem();
668
669 if ( (m_selection == wxNOT_FOUND &&
670 (!newId.IsOk() || newId == m_tree->GetRootItem())) ||
671 (m_selection != wxNOT_FOUND && newId == m_treeIds[m_selection]) )
672 {
673 // this event can only come when we modify the tree selection ourselves
674 // so we should simply ignore it
675 return;
676 }
677
678 int newPos = DoInternalFindPageById(newId);
679
680 if ( newPos != wxNOT_FOUND )
681 SetSelection( newPos );
682}
683
684void wxTreebook::OnTreeNodeExpandedCollapsed(wxTreeEvent & event)
685{
686 wxTreeItemId nodeId = event.GetItem();
687 if ( !nodeId.IsOk() || nodeId == m_tree->GetRootItem() )
688 return;
689 int pagePos = DoInternalFindPageById(nodeId);
690 wxCHECK_RET( pagePos != wxNOT_FOUND, wxT("Internal problem in wxTreebook!..") );
691
692 wxTreebookEvent ev(m_tree->IsExpanded(nodeId)
693 ? wxEVT_COMMAND_TREEBOOK_NODE_EXPANDED
694 : wxEVT_COMMAND_TREEBOOK_NODE_COLLAPSED,
695 m_windowId);
696
697 ev.SetSelection(pagePos);
698 ev.SetOldSelection(pagePos);
699 ev.SetEventObject(this);
700
701 GetEventHandler()->ProcessEvent(ev);
702}
703
704// ----------------------------------------------------------------------------
705// wxTreebook geometry management
706// ----------------------------------------------------------------------------
707
708wxSize wxTreebook::GetTreeSize() const
709{
710 const wxSize sizeClient = GetClientSize(),
711 sizeBorder = m_tree->GetSize() - m_tree->GetClientSize(),
712 sizeTree = m_tree->GetBestSize() + sizeBorder;
713
714 wxSize size;
715
716 size.x = sizeTree.x;
717 size.y = sizeClient.y;
718
719 return size;
720}
721
722wxRect wxTreebook::GetPageRect() const
723{
724 const wxSize sizeTree = m_tree->GetSize();
725
726 wxPoint pt;
727 wxRect rectPage(pt, GetClientSize());
728 switch ( GetWindowStyle() & wxTBK_ALIGN_MASK )
729 {
730 default:
731 wxFAIL_MSG( _T("unexpected wxTreebook alignment") );
732 // fall through
733
734 case wxTBK_LEFT:
735 rectPage.x = sizeTree.x; // + MARGIN;
736 // fall through
737
738 case wxTBK_RIGHT:
739 rectPage.width -= sizeTree.x; // + MARGIN;
740 break;
741 }
742
743 return rectPage;
744}
745
746void wxTreebook::OnSize(wxSizeEvent& event)
747{
748 event.Skip();
749
750 if ( !m_tree )
751 {
752 // we're not fully created yet
753 return;
754 }
755
756 // resize the list control and the page area to fit inside our new size
757 const wxSize sizeClient = GetClientSize(),
758 sizeBorder = m_tree->GetSize() - m_tree->GetClientSize(),
759 sizeTree = GetTreeSize();
760
761 m_tree->SetClientSize( sizeTree.x - sizeBorder.x, sizeTree.y - sizeBorder.y );
762
763 const wxSize sizeNew = m_tree->GetSize();
764 wxPoint posTree;
765 switch ( GetWindowStyle() & wxTBK_ALIGN_MASK )
766 {
767 default:
768 wxFAIL_MSG( _T("unexpected wxTreebook alignment") );
769 // fall through
770
771 case wxTBK_LEFT:
772 // posTree is already ok
773 break;
774
775 case wxTBK_RIGHT:
776 posTree.x = sizeClient.x - sizeNew.x;
777 break;
778 }
779
780 if ( m_tree->GetPosition() != posTree )
781 m_tree->Move(posTree);
782
783 // resize the currently shown page
784 wxTreebookPage *page = DoGetCurrentPage();
785 if ( page )
786 {
787 wxRect rectPage = GetPageRect();
788 page->SetSize(rectPage);
789 }
790}
791
792wxTreebookPage * wxTreebook::DoGetCurrentPage() const
793{
794 if ( m_selection == wxNOT_FOUND )
795 return NULL;
796
797 wxTreebookPage *page = wxBookCtrlBase::GetPage(m_selection);
798 if ( !page && m_actualSelection != wxNOT_FOUND )
799 {
800 page = wxBookCtrlBase::GetPage(m_actualSelection);
801 }
802
803 return page;
804}
805
806#endif // wxUSE_TREEBOOK
807