1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/aui/auibook.cpp
3 // Purpose: wxaui: wx advanced user interface - notebook
4 // Author: Benjamin I. Williams
5 // Modified by: Jens Lody
7 // Copyright: (C) Copyright 2006, Kirix Corporation, All Rights Reserved
8 // Licence: wxWindows Library Licence, Version 3.1
9 ///////////////////////////////////////////////////////////////////////////////
11 // ----------------------------------------------------------------------------
13 // ----------------------------------------------------------------------------
15 #include "wx/wxprec.h"
23 #include "wx/aui/auibook.h"
26 #include "wx/settings.h"
27 #include "wx/clientdc.h"
30 #include "wx/aui/tabmdi.h"
33 #include "wx/osx/private.h"
36 #include "wx/arrimpl.cpp"
37 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray
)
38 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray
)
40 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
, wxAuiNotebookEvent
);
41 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED
, wxAuiNotebookEvent
);
42 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, wxAuiNotebookEvent
);
43 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
, wxAuiNotebookEvent
);
44 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, wxAuiNotebookEvent
);
45 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, wxAuiNotebookEvent
);
46 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, wxAuiNotebookEvent
);
47 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_CANCEL_DRAG
, wxAuiNotebookEvent
);
48 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, wxAuiNotebookEvent
);
49 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
, wxAuiNotebookEvent
);
50 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
, wxAuiNotebookEvent
);
51 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE
, wxAuiNotebookEvent
);
52 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
, wxAuiNotebookEvent
);
53 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
, wxAuiNotebookEvent
);
54 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
, wxAuiNotebookEvent
);
55 wxDEFINE_EVENT(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
, wxAuiNotebookEvent
);
57 IMPLEMENT_CLASS(wxAuiNotebook
, wxControl
)
58 IMPLEMENT_CLASS(wxAuiTabCtrl
, wxControl
)
59 IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent
, wxBookCtrlEvent
)
62 // -- wxAuiTabContainer class implementation --
65 // wxAuiTabContainer is a class which contains information about each
66 // tab. It also can render an entire tab control to a specified DC.
67 // It's not a window class itself, because this code will be used by
68 // the wxFrameMananger, where it is disadvantageous to have separate
69 // windows for each tab control in the case of "docked tabs"
71 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window
72 // which can be used as a tab control in the normal sense.
75 wxAuiTabContainer::wxAuiTabContainer()
79 m_art
= new wxAuiDefaultTabArt
;
81 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
82 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
83 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
84 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
87 wxAuiTabContainer::~wxAuiTabContainer()
92 void wxAuiTabContainer::SetArtProvider(wxAuiTabArt
* art
)
99 m_art
->SetFlags(m_flags
);
103 wxAuiTabArt
* wxAuiTabContainer::GetArtProvider() const
108 void wxAuiTabContainer::SetFlags(unsigned int flags
)
112 // check for new close button settings
113 RemoveButton(wxAUI_BUTTON_LEFT
);
114 RemoveButton(wxAUI_BUTTON_RIGHT
);
115 RemoveButton(wxAUI_BUTTON_WINDOWLIST
);
116 RemoveButton(wxAUI_BUTTON_CLOSE
);
119 if (flags
& wxAUI_NB_SCROLL_BUTTONS
)
121 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
122 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
125 if (flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
127 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
130 if (flags
& wxAUI_NB_CLOSE_BUTTON
)
132 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
137 m_art
->SetFlags(m_flags
);
141 unsigned int wxAuiTabContainer::GetFlags() const
147 void wxAuiTabContainer::SetNormalFont(const wxFont
& font
)
149 m_art
->SetNormalFont(font
);
152 void wxAuiTabContainer::SetSelectedFont(const wxFont
& font
)
154 m_art
->SetSelectedFont(font
);
157 void wxAuiTabContainer::SetMeasuringFont(const wxFont
& font
)
159 m_art
->SetMeasuringFont(font
);
162 void wxAuiTabContainer::SetColour(const wxColour
& colour
)
164 m_art
->SetColour(colour
);
167 void wxAuiTabContainer::SetActiveColour(const wxColour
& colour
)
169 m_art
->SetActiveColour(colour
);
172 void wxAuiTabContainer::SetRect(const wxRect
& rect
)
178 m_art
->SetSizingInfo(rect
.GetSize(), m_pages
.GetCount());
182 bool wxAuiTabContainer::AddPage(wxWindow
* page
,
183 const wxAuiNotebookPage
& info
)
185 wxAuiNotebookPage page_info
;
187 page_info
.window
= page
;
189 m_pages
.Add(page_info
);
191 // let the art provider know how many pages we have
194 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
200 bool wxAuiTabContainer::InsertPage(wxWindow
* page
,
201 const wxAuiNotebookPage
& info
,
204 wxAuiNotebookPage page_info
;
206 page_info
.window
= page
;
208 if (idx
>= m_pages
.GetCount())
209 m_pages
.Add(page_info
);
211 m_pages
.Insert(page_info
, idx
);
213 // let the art provider know how many pages we have
216 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
222 bool wxAuiTabContainer::MovePage(wxWindow
* page
,
225 int idx
= GetIdxFromWindow(page
);
229 // get page entry, make a copy of it
230 wxAuiNotebookPage p
= GetPage(idx
);
232 // remove old page entry
235 // insert page where it should be
236 InsertPage(page
, p
, new_idx
);
241 bool wxAuiTabContainer::RemovePage(wxWindow
* wnd
)
243 size_t i
, page_count
= m_pages
.GetCount();
244 for (i
= 0; i
< page_count
; ++i
)
246 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
247 if (page
.window
== wnd
)
251 // let the art provider know how many pages we have
254 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
264 bool wxAuiTabContainer::SetActivePage(wxWindow
* wnd
)
268 size_t i
, page_count
= m_pages
.GetCount();
269 for (i
= 0; i
< page_count
; ++i
)
271 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
272 if (page
.window
== wnd
)
286 void wxAuiTabContainer::SetNoneActive()
288 size_t i
, page_count
= m_pages
.GetCount();
289 for (i
= 0; i
< page_count
; ++i
)
291 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
296 bool wxAuiTabContainer::SetActivePage(size_t page
)
298 if (page
>= m_pages
.GetCount())
301 return SetActivePage(m_pages
.Item(page
).window
);
304 int wxAuiTabContainer::GetActivePage() const
306 size_t i
, page_count
= m_pages
.GetCount();
307 for (i
= 0; i
< page_count
; ++i
)
309 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
317 wxWindow
* wxAuiTabContainer::GetWindowFromIdx(size_t idx
) const
319 if (idx
>= m_pages
.GetCount())
322 return m_pages
[idx
].window
;
325 int wxAuiTabContainer::GetIdxFromWindow(wxWindow
* wnd
) const
327 const size_t page_count
= m_pages
.GetCount();
328 for ( size_t i
= 0; i
< page_count
; ++i
)
330 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
331 if (page
.window
== wnd
)
337 wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
)
339 wxASSERT_MSG(idx
< m_pages
.GetCount(), wxT("Invalid Page index"));
344 const wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
) const
346 wxASSERT_MSG(idx
< m_pages
.GetCount(), wxT("Invalid Page index"));
351 wxAuiNotebookPageArray
& wxAuiTabContainer::GetPages()
356 size_t wxAuiTabContainer::GetPageCount() const
358 return m_pages
.GetCount();
361 void wxAuiTabContainer::AddButton(int id
,
363 const wxBitmap
& normalBitmap
,
364 const wxBitmap
& disabledBitmap
)
366 wxAuiTabContainerButton button
;
368 button
.bitmap
= normalBitmap
;
369 button
.disBitmap
= disabledBitmap
;
370 button
.location
= location
;
371 button
.curState
= wxAUI_BUTTON_STATE_NORMAL
;
373 m_buttons
.Add(button
);
376 void wxAuiTabContainer::RemoveButton(int id
)
378 size_t i
, button_count
= m_buttons
.GetCount();
380 for (i
= 0; i
< button_count
; ++i
)
382 if (m_buttons
.Item(i
).id
== id
)
384 m_buttons
.RemoveAt(i
);
392 size_t wxAuiTabContainer::GetTabOffset() const
397 void wxAuiTabContainer::SetTabOffset(size_t offset
)
399 m_tabOffset
= offset
;
405 // Render() renders the tab catalog to the specified DC
406 // It is a virtual function and can be overridden to
407 // provide custom drawing capabilities
408 void wxAuiTabContainer::Render(wxDC
* raw_dc
, wxWindow
* wnd
)
410 if (!raw_dc
|| !raw_dc
->IsOk())
415 // use the same layout direction as the window DC uses to ensure that the
416 // text is rendered correctly
417 dc
.SetLayoutDirection(raw_dc
->GetLayoutDirection());
421 size_t page_count
= m_pages
.GetCount();
422 size_t button_count
= m_buttons
.GetCount();
424 // create off-screen bitmap
425 bmp
.Create(m_rect
.GetWidth(), m_rect
.GetHeight());
426 dc
.SelectObject(bmp
);
431 // find out if size of tabs is larger than can be
432 // afforded on screen
434 int visible_width
= 0;
435 for (i
= 0; i
< page_count
; ++i
)
437 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
439 // determine if a close button is on this tab
440 bool close_button
= false;
441 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
442 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
449 wxSize size
= m_art
->GetTabSize(dc
,
455 wxAUI_BUTTON_STATE_NORMAL
:
456 wxAUI_BUTTON_STATE_HIDDEN
,
459 if (i
+1 < page_count
)
460 total_width
+= x_extent
;
462 total_width
+= size
.x
;
464 if (i
>= m_tabOffset
)
466 if (i
+1 < page_count
)
467 visible_width
+= x_extent
;
469 visible_width
+= size
.x
;
473 if (total_width
> m_rect
.GetWidth() || m_tabOffset
!= 0)
475 // show left/right buttons
476 for (i
= 0; i
< button_count
; ++i
)
478 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
479 if (button
.id
== wxAUI_BUTTON_LEFT
||
480 button
.id
== wxAUI_BUTTON_RIGHT
)
482 button
.curState
&= ~wxAUI_BUTTON_STATE_HIDDEN
;
488 // hide left/right buttons
489 for (i
= 0; i
< button_count
; ++i
)
491 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
492 if (button
.id
== wxAUI_BUTTON_LEFT
||
493 button
.id
== wxAUI_BUTTON_RIGHT
)
495 button
.curState
|= wxAUI_BUTTON_STATE_HIDDEN
;
500 // determine whether left button should be enabled
501 for (i
= 0; i
< button_count
; ++i
)
503 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
504 if (button
.id
== wxAUI_BUTTON_LEFT
)
506 if (m_tabOffset
== 0)
507 button
.curState
|= wxAUI_BUTTON_STATE_DISABLED
;
509 button
.curState
&= ~wxAUI_BUTTON_STATE_DISABLED
;
511 if (button
.id
== wxAUI_BUTTON_RIGHT
)
513 if (visible_width
< m_rect
.GetWidth() - ((int)button_count
*16))
514 button
.curState
|= wxAUI_BUTTON_STATE_DISABLED
;
516 button
.curState
&= ~wxAUI_BUTTON_STATE_DISABLED
;
523 m_art
->DrawBackground(dc
, wnd
, m_rect
);
526 int left_buttons_width
= 0;
527 int right_buttons_width
= 0;
531 // draw the buttons on the right side
532 offset
= m_rect
.x
+ m_rect
.width
;
533 for (i
= 0; i
< button_count
; ++i
)
535 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
537 if (button
.location
!= wxRIGHT
)
539 if (button
.curState
& wxAUI_BUTTON_STATE_HIDDEN
)
542 wxRect button_rect
= m_rect
;
544 button_rect
.SetWidth(offset
);
546 m_art
->DrawButton(dc
,
554 offset
-= button
.rect
.GetWidth();
555 right_buttons_width
+= button
.rect
.GetWidth();
562 // draw the buttons on the left side
564 for (i
= 0; i
< button_count
; ++i
)
566 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
568 if (button
.location
!= wxLEFT
)
570 if (button
.curState
& wxAUI_BUTTON_STATE_HIDDEN
)
573 wxRect
button_rect(offset
, 1, 1000, m_rect
.height
);
575 m_art
->DrawButton(dc
,
583 offset
+= button
.rect
.GetWidth();
584 left_buttons_width
+= button
.rect
.GetWidth();
587 offset
= left_buttons_width
;
590 offset
+= m_art
->GetIndentSize();
593 // prepare the tab-close-button array
594 // make sure tab button entries which aren't used are marked as hidden
595 for (i
= page_count
; i
< m_tabCloseButtons
.GetCount(); ++i
)
596 m_tabCloseButtons
.Item(i
).curState
= wxAUI_BUTTON_STATE_HIDDEN
;
598 // make sure there are enough tab button entries to accommodate all tabs
599 while (m_tabCloseButtons
.GetCount() < page_count
)
601 wxAuiTabContainerButton tempbtn
;
602 tempbtn
.id
= wxAUI_BUTTON_CLOSE
;
603 tempbtn
.location
= wxCENTER
;
604 tempbtn
.curState
= wxAUI_BUTTON_STATE_HIDDEN
;
605 m_tabCloseButtons
.Add(tempbtn
);
609 // buttons before the tab offset must be set to hidden
610 for (i
= 0; i
< m_tabOffset
; ++i
)
612 m_tabCloseButtons
.Item(i
).curState
= wxAUI_BUTTON_STATE_HIDDEN
;
619 int active_offset
= 0;
623 wxRect rect
= m_rect
;
625 rect
.height
= m_rect
.height
;
627 for (i
= m_tabOffset
; i
< page_count
; ++i
)
629 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
630 wxAuiTabContainerButton
& tab_button
= m_tabCloseButtons
.Item(i
);
632 // determine if a close button is on this tab
633 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
634 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
636 if (tab_button
.curState
== wxAUI_BUTTON_STATE_HIDDEN
)
638 tab_button
.id
= wxAUI_BUTTON_CLOSE
;
639 tab_button
.curState
= wxAUI_BUTTON_STATE_NORMAL
;
640 tab_button
.location
= wxCENTER
;
645 tab_button
.curState
= wxAUI_BUTTON_STATE_HIDDEN
;
649 rect
.width
= m_rect
.width
- right_buttons_width
- offset
- 2;
666 active_offset
= offset
;
674 // make sure to deactivate buttons which are off the screen to the right
675 for (++i
; i
< m_tabCloseButtons
.GetCount(); ++i
)
677 m_tabCloseButtons
.Item(i
).curState
= wxAUI_BUTTON_STATE_HIDDEN
;
681 // draw the active tab again so it stands in the foreground
682 if (active
>= m_tabOffset
&& active
< m_pages
.GetCount())
684 wxAuiNotebookPage
& page
= m_pages
.Item(active
);
686 wxAuiTabContainerButton
& tab_button
= m_tabCloseButtons
.Item(active
);
688 rect
.x
= active_offset
;
700 raw_dc
->Blit(m_rect
.x
, m_rect
.y
,
701 m_rect
.GetWidth(), m_rect
.GetHeight(),
705 // Is the tab visible?
706 bool wxAuiTabContainer::IsTabVisible(int tabPage
, int tabOffset
, wxDC
* dc
, wxWindow
* wnd
)
708 if (!dc
|| !dc
->IsOk())
712 size_t page_count
= m_pages
.GetCount();
713 size_t button_count
= m_buttons
.GetCount();
715 // Hasn't been rendered yet; assume it's visible
716 if (m_tabCloseButtons
.GetCount() < page_count
)
719 // First check if both buttons are disabled - if so, there's no need to
720 // check further for visibility.
721 int arrowButtonVisibleCount
= 0;
722 for (i
= 0; i
< button_count
; ++i
)
724 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
725 if (button
.id
== wxAUI_BUTTON_LEFT
||
726 button
.id
== wxAUI_BUTTON_RIGHT
)
728 if ((button
.curState
& wxAUI_BUTTON_STATE_HIDDEN
) == 0)
729 arrowButtonVisibleCount
++;
733 // Tab must be visible
734 if (arrowButtonVisibleCount
== 0)
737 // If tab is less than the given offset, it must be invisible by definition
738 if (tabPage
< tabOffset
)
742 int left_buttons_width
= 0;
743 int right_buttons_width
= 0;
747 // calculate size of the buttons on the right side
748 offset
= m_rect
.x
+ m_rect
.width
;
749 for (i
= 0; i
< button_count
; ++i
)
751 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
753 if (button
.location
!= wxRIGHT
)
755 if (button
.curState
& wxAUI_BUTTON_STATE_HIDDEN
)
758 offset
-= button
.rect
.GetWidth();
759 right_buttons_width
+= button
.rect
.GetWidth();
764 // calculate size of the buttons on the left side
765 for (i
= 0; i
< button_count
; ++i
)
767 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
769 if (button
.location
!= wxLEFT
)
771 if (button
.curState
& wxAUI_BUTTON_STATE_HIDDEN
)
774 offset
+= button
.rect
.GetWidth();
775 left_buttons_width
+= button
.rect
.GetWidth();
778 offset
= left_buttons_width
;
781 offset
+= m_art
->GetIndentSize();
785 wxRect rect
= m_rect
;
787 rect
.height
= m_rect
.height
;
789 // See if the given page is visible at the given tab offset (effectively scroll position)
790 for (i
= tabOffset
; i
< page_count
; ++i
)
792 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
793 wxAuiTabContainerButton
& tab_button
= m_tabCloseButtons
.Item(i
);
796 rect
.width
= m_rect
.width
- right_buttons_width
- offset
- 2;
799 return false; // haven't found the tab, and we've run out of space, so return false
802 m_art
->GetTabSize(*dc
,
812 if (i
== (size_t) tabPage
)
814 // If not all of the tab is visible, and supposing there's space to display it all,
815 // we could do better so we return false.
816 if (((m_rect
.width
- right_buttons_width
- offset
- 2) <= 0) && ((m_rect
.width
- right_buttons_width
- left_buttons_width
) > x_extent
))
823 // Shouldn't really get here, but if it does, assume the tab is visible to prevent
824 // further looping in calling code.
828 // Make the tab visible if it wasn't already
829 void wxAuiTabContainer::MakeTabVisible(int tabPage
, wxWindow
* win
)
832 if (!IsTabVisible(tabPage
, GetTabOffset(), & dc
, win
))
835 for (i
= 0; i
< (int) m_pages
.GetCount(); i
++)
837 if (IsTabVisible(tabPage
, i
, & dc
, win
))
847 // TabHitTest() tests if a tab was hit, passing the window pointer
848 // back if that condition was fulfilled. The function returns
849 // true if a tab was hit, otherwise false
850 bool wxAuiTabContainer::TabHitTest(int x
, int y
, wxWindow
** hit
) const
852 if (!m_rect
.Contains(x
,y
))
855 wxAuiTabContainerButton
* btn
= NULL
;
856 if (ButtonHitTest(x
, y
, &btn
) && !(btn
->curState
& wxAUI_BUTTON_STATE_DISABLED
))
858 if (m_buttons
.Index(*btn
) != wxNOT_FOUND
)
862 size_t i
, page_count
= m_pages
.GetCount();
864 for (i
= m_tabOffset
; i
< page_count
; ++i
)
866 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
867 if (page
.rect
.Contains(x
,y
))
878 // ButtonHitTest() tests if a button was hit. The function returns
879 // true if a button was hit, otherwise false
880 bool wxAuiTabContainer::ButtonHitTest(int x
, int y
,
881 wxAuiTabContainerButton
** hit
) const
883 if (!m_rect
.Contains(x
,y
))
886 size_t i
, button_count
;
889 button_count
= m_buttons
.GetCount();
890 for (i
= 0; i
< button_count
; ++i
)
892 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
893 if (button
.rect
.Contains(x
,y
) &&
894 !(button
.curState
& wxAUI_BUTTON_STATE_HIDDEN
))
902 button_count
= m_tabCloseButtons
.GetCount();
903 for (i
= 0; i
< button_count
; ++i
)
905 wxAuiTabContainerButton
& button
= m_tabCloseButtons
.Item(i
);
906 if (button
.rect
.Contains(x
,y
) &&
907 !(button
.curState
& (wxAUI_BUTTON_STATE_HIDDEN
|
908 wxAUI_BUTTON_STATE_DISABLED
)))
921 // the utility function ShowWnd() is the same as show,
922 // except it handles wxAuiMDIChildFrame windows as well,
923 // as the Show() method on this class is "unplugged"
924 static void ShowWnd(wxWindow
* wnd
, bool show
)
927 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
929 wxAuiMDIChildFrame
* cf
= (wxAuiMDIChildFrame
*)wnd
;
940 // DoShowHide() this function shows the active window, then
941 // hides all of the other windows (in that order)
942 void wxAuiTabContainer::DoShowHide()
944 wxAuiNotebookPageArray
& pages
= GetPages();
945 size_t i
, page_count
= pages
.GetCount();
947 // show new active page first
948 for (i
= 0; i
< page_count
; ++i
)
950 wxAuiNotebookPage
& page
= pages
.Item(i
);
953 ShowWnd(page
.window
, true);
958 // hide all other pages
959 for (i
= 0; i
< page_count
; ++i
)
961 wxAuiNotebookPage
& page
= pages
.Item(i
);
963 ShowWnd(page
.window
, false);
972 // -- wxAuiTabCtrl class implementation --
976 BEGIN_EVENT_TABLE(wxAuiTabCtrl
, wxControl
)
977 EVT_PAINT(wxAuiTabCtrl::OnPaint
)
978 EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground
)
979 EVT_SIZE(wxAuiTabCtrl::OnSize
)
980 EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown
)
981 EVT_LEFT_DCLICK(wxAuiTabCtrl::OnLeftDClick
)
982 EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp
)
983 EVT_MIDDLE_DOWN(wxAuiTabCtrl::OnMiddleDown
)
984 EVT_MIDDLE_UP(wxAuiTabCtrl::OnMiddleUp
)
985 EVT_RIGHT_DOWN(wxAuiTabCtrl::OnRightDown
)
986 EVT_RIGHT_UP(wxAuiTabCtrl::OnRightUp
)
987 EVT_MOTION(wxAuiTabCtrl::OnMotion
)
988 EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow
)
989 EVT_AUINOTEBOOK_BUTTON(wxID_ANY
, wxAuiTabCtrl::OnButton
)
990 EVT_SET_FOCUS(wxAuiTabCtrl::OnSetFocus
)
991 EVT_KILL_FOCUS(wxAuiTabCtrl::OnKillFocus
)
992 EVT_CHAR(wxAuiTabCtrl::OnChar
)
993 EVT_MOUSE_CAPTURE_LOST(wxAuiTabCtrl::OnCaptureLost
)
997 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow
* parent
,
1001 long style
) : wxControl(parent
, id
, pos
, size
, style
)
1003 SetName(wxT("wxAuiTabCtrl"));
1004 m_clickPt
= wxDefaultPosition
;
1005 m_isDragging
= false;
1006 m_hoverButton
= NULL
;
1007 m_pressedButton
= NULL
;
1010 wxAuiTabCtrl::~wxAuiTabCtrl()
1014 void wxAuiTabCtrl::OnPaint(wxPaintEvent
&)
1018 dc
.SetFont(GetFont());
1020 if (GetPageCount() > 0)
1024 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent
& WXUNUSED(evt
))
1028 void wxAuiTabCtrl::OnSize(wxSizeEvent
& evt
)
1030 wxSize s
= evt
.GetSize();
1031 wxRect
r(0, 0, s
.GetWidth(), s
.GetHeight());
1035 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent
& evt
)
1038 m_clickPt
= wxDefaultPosition
;
1039 m_isDragging
= false;
1041 m_pressedButton
= NULL
;
1045 if (TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
1047 int new_selection
= GetIdxFromWindow(wnd
);
1049 // wxAuiNotebooks always want to receive this event
1050 // even if the tab is already active, because they may
1051 // have multiple tab controls
1052 if (new_selection
!= GetActivePage() ||
1053 GetParent()->IsKindOf(CLASSINFO(wxAuiNotebook
)))
1055 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
1056 e
.SetSelection(new_selection
);
1057 e
.SetOldSelection(GetActivePage());
1058 e
.SetEventObject(this);
1059 GetEventHandler()->ProcessEvent(e
);
1062 m_clickPt
.x
= evt
.m_x
;
1063 m_clickPt
.y
= evt
.m_y
;
1069 m_pressedButton
= m_hoverButton
;
1070 m_pressedButton
->curState
= wxAUI_BUTTON_STATE_PRESSED
;
1076 void wxAuiTabCtrl::OnCaptureLost(wxMouseCaptureLostEvent
& WXUNUSED(event
))
1080 m_isDragging
= false;
1082 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_CANCEL_DRAG
, m_windowId
);
1083 evt
.SetSelection(GetIdxFromWindow(m_clickTab
));
1084 evt
.SetOldSelection(evt
.GetSelection());
1085 evt
.SetEventObject(this);
1086 GetEventHandler()->ProcessEvent(evt
);
1090 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent
& evt
)
1092 if (GetCapture() == this)
1097 m_isDragging
= false;
1099 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, m_windowId
);
1100 evt
.SetSelection(GetIdxFromWindow(m_clickTab
));
1101 evt
.SetOldSelection(evt
.GetSelection());
1102 evt
.SetEventObject(this);
1103 GetEventHandler()->ProcessEvent(evt
);
1108 if (m_pressedButton
)
1110 // make sure we're still clicking the button
1111 wxAuiTabContainerButton
* button
= NULL
;
1112 if (!ButtonHitTest(evt
.m_x
, evt
.m_y
, &button
) ||
1113 button
->curState
& wxAUI_BUTTON_STATE_DISABLED
)
1116 if (button
!= m_pressedButton
)
1118 m_pressedButton
= NULL
;
1125 if (!(m_pressedButton
->curState
& wxAUI_BUTTON_STATE_DISABLED
))
1127 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, m_windowId
);
1128 evt
.SetSelection(GetIdxFromWindow(m_clickTab
));
1129 evt
.SetInt(m_pressedButton
->id
);
1130 evt
.SetEventObject(this);
1131 GetEventHandler()->ProcessEvent(evt
);
1134 m_pressedButton
= NULL
;
1137 m_clickPt
= wxDefaultPosition
;
1138 m_isDragging
= false;
1142 void wxAuiTabCtrl::OnMiddleUp(wxMouseEvent
& evt
)
1144 wxWindow
* wnd
= NULL
;
1145 if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
1148 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
, m_windowId
);
1149 e
.SetEventObject(this);
1150 e
.SetSelection(GetIdxFromWindow(wnd
));
1151 GetEventHandler()->ProcessEvent(e
);
1154 void wxAuiTabCtrl::OnMiddleDown(wxMouseEvent
& evt
)
1156 wxWindow
* wnd
= NULL
;
1157 if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
1160 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
, m_windowId
);
1161 e
.SetEventObject(this);
1162 e
.SetSelection(GetIdxFromWindow(wnd
));
1163 GetEventHandler()->ProcessEvent(e
);
1166 void wxAuiTabCtrl::OnRightUp(wxMouseEvent
& evt
)
1168 wxWindow
* wnd
= NULL
;
1169 if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
1172 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
, m_windowId
);
1173 e
.SetEventObject(this);
1174 e
.SetSelection(GetIdxFromWindow(wnd
));
1175 GetEventHandler()->ProcessEvent(e
);
1178 void wxAuiTabCtrl::OnRightDown(wxMouseEvent
& evt
)
1180 wxWindow
* wnd
= NULL
;
1181 if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
1184 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
, m_windowId
);
1185 e
.SetEventObject(this);
1186 e
.SetSelection(GetIdxFromWindow(wnd
));
1187 GetEventHandler()->ProcessEvent(e
);
1190 void wxAuiTabCtrl::OnLeftDClick(wxMouseEvent
& evt
)
1193 wxAuiTabContainerButton
* button
;
1194 if (!TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
) && !ButtonHitTest(evt
.m_x
, evt
.m_y
, &button
))
1196 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
, m_windowId
);
1197 e
.SetEventObject(this);
1198 GetEventHandler()->ProcessEvent(e
);
1202 void wxAuiTabCtrl::OnMotion(wxMouseEvent
& evt
)
1204 wxPoint pos
= evt
.GetPosition();
1206 // check if the mouse is hovering above a button
1207 wxAuiTabContainerButton
* button
;
1208 if (ButtonHitTest(pos
.x
, pos
.y
, &button
) && !(button
->curState
& wxAUI_BUTTON_STATE_DISABLED
))
1210 if (m_hoverButton
&& button
!= m_hoverButton
)
1212 m_hoverButton
->curState
= wxAUI_BUTTON_STATE_NORMAL
;
1213 m_hoverButton
= NULL
;
1218 if (button
->curState
!= wxAUI_BUTTON_STATE_HOVER
)
1220 button
->curState
= wxAUI_BUTTON_STATE_HOVER
;
1224 m_hoverButton
= button
;
1232 m_hoverButton
->curState
= wxAUI_BUTTON_STATE_NORMAL
;
1233 m_hoverButton
= NULL
;
1240 if (!evt
.LeftIsDown() || m_clickPt
== wxDefaultPosition
)
1245 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, m_windowId
);
1246 evt
.SetSelection(GetIdxFromWindow(m_clickTab
));
1247 evt
.SetOldSelection(evt
.GetSelection());
1248 evt
.SetEventObject(this);
1249 GetEventHandler()->ProcessEvent(evt
);
1254 int drag_x_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_X
);
1255 int drag_y_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_Y
);
1257 if (abs(pos
.x
- m_clickPt
.x
) > drag_x_threshold
||
1258 abs(pos
.y
- m_clickPt
.y
) > drag_y_threshold
)
1260 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, m_windowId
);
1261 evt
.SetSelection(GetIdxFromWindow(m_clickTab
));
1262 evt
.SetOldSelection(evt
.GetSelection());
1263 evt
.SetEventObject(this);
1264 GetEventHandler()->ProcessEvent(evt
);
1266 m_isDragging
= true;
1270 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
))
1274 m_hoverButton
->curState
= wxAUI_BUTTON_STATE_NORMAL
;
1275 m_hoverButton
= NULL
;
1281 void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent
& event
)
1283 int button
= event
.GetInt();
1285 if (button
== wxAUI_BUTTON_LEFT
|| button
== wxAUI_BUTTON_RIGHT
)
1287 if (button
== wxAUI_BUTTON_LEFT
)
1289 if (GetTabOffset() > 0)
1291 SetTabOffset(GetTabOffset()-1);
1298 SetTabOffset(GetTabOffset()+1);
1303 else if (button
== wxAUI_BUTTON_WINDOWLIST
)
1305 int idx
= GetArtProvider()->ShowDropDown(this, m_pages
, GetActivePage());
1309 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
1310 e
.SetSelection(idx
);
1311 e
.SetOldSelection(GetActivePage());
1312 e
.SetEventObject(this);
1313 GetEventHandler()->ProcessEvent(e
);
1322 void wxAuiTabCtrl::OnSetFocus(wxFocusEvent
& WXUNUSED(event
))
1327 void wxAuiTabCtrl::OnKillFocus(wxFocusEvent
& WXUNUSED(event
))
1332 void wxAuiTabCtrl::OnChar(wxKeyEvent
& event
)
1334 if (GetActivePage() == -1)
1340 // We can't leave tab processing to the system; on Windows, tabs and keys
1341 // get eaten by the system and not processed properly if we specify both
1342 // wxTAB_TRAVERSAL and wxWANTS_CHARS. And if we specify just wxTAB_TRAVERSAL,
1343 // we don't key arrow key events.
1345 int key
= event
.GetKeyCode();
1347 if (key
== WXK_NUMPAD_PAGEUP
)
1349 if (key
== WXK_NUMPAD_PAGEDOWN
)
1351 if (key
== WXK_NUMPAD_HOME
)
1353 if (key
== WXK_NUMPAD_END
)
1355 if (key
== WXK_NUMPAD_LEFT
)
1357 if (key
== WXK_NUMPAD_RIGHT
)
1360 if (key
== WXK_TAB
|| key
== WXK_PAGEUP
|| key
== WXK_PAGEDOWN
)
1362 bool bCtrlDown
= event
.ControlDown();
1363 bool bShiftDown
= event
.ShiftDown();
1365 bool bForward
= (key
== WXK_TAB
&& !bShiftDown
) || (key
== WXK_PAGEDOWN
);
1366 bool bWindowChange
= (key
== WXK_PAGEUP
) || (key
== WXK_PAGEDOWN
) || bCtrlDown
;
1367 bool bFromTab
= (key
== WXK_TAB
);
1369 wxAuiNotebook
* nb
= wxDynamicCast(GetParent(), wxAuiNotebook
);
1376 wxNavigationKeyEvent keyEvent
;
1377 keyEvent
.SetDirection(bForward
);
1378 keyEvent
.SetWindowChange(bWindowChange
);
1379 keyEvent
.SetFromTab(bFromTab
);
1380 keyEvent
.SetEventObject(nb
);
1382 if (!nb
->GetEventHandler()->ProcessEvent(keyEvent
))
1384 // Not processed? Do an explicit tab into the page.
1385 wxWindow
* win
= GetWindowFromIdx(GetActivePage());
1392 if (m_pages
.GetCount() < 2)
1400 int forwardKey
, backwardKey
;
1401 if (GetLayoutDirection() == wxLayout_RightToLeft
)
1403 forwardKey
= WXK_LEFT
;
1404 backwardKey
= WXK_RIGHT
;
1408 forwardKey
= WXK_RIGHT
;
1409 backwardKey
= WXK_LEFT
;
1412 if (key
== forwardKey
)
1414 if (m_pages
.GetCount() > 1)
1416 if (GetActivePage() == -1)
1418 else if (GetActivePage() < (int) (m_pages
.GetCount() - 1))
1419 newPage
= GetActivePage() + 1;
1422 else if (key
== backwardKey
)
1424 if (m_pages
.GetCount() > 1)
1426 if (GetActivePage() == -1)
1427 newPage
= (int) (m_pages
.GetCount() - 1);
1428 else if (GetActivePage() > 0)
1429 newPage
= GetActivePage() - 1;
1432 else if (key
== WXK_HOME
)
1436 else if (key
== WXK_END
)
1438 newPage
= (int) (m_pages
.GetCount() - 1);
1445 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
1446 e
.SetSelection(newPage
);
1447 e
.SetOldSelection(newPage
);
1448 e
.SetEventObject(this);
1449 this->GetEventHandler()->ProcessEvent(e
);
1455 // wxTabFrame is an interesting case. It's important that all child pages
1456 // of the multi-notebook control are all actually children of that control
1457 // (and not grandchildren). wxTabFrame facilitates this. There is one
1458 // instance of wxTabFrame for each tab control inside the multi-notebook.
1459 // It's important to know that wxTabFrame is not a real window, but it merely
1460 // used to capture the dimensions/positioning of the internal tab control and
1461 // it's managed page windows
1463 class wxTabFrame
: public wxWindow
1470 m_rect
= wxRect(0,0,200,200);
1471 m_tabCtrlHeight
= 20;
1479 void SetTabCtrlHeight(int h
)
1481 m_tabCtrlHeight
= h
;
1485 void DoSetSize(int x
, int y
,
1486 int width
, int height
,
1487 int WXUNUSED(sizeFlags
= wxSIZE_AUTO
))
1489 m_rect
= wxRect(x
, y
, width
, height
);
1493 void DoGetClientSize(int* x
, int* y
) const
1500 bool Show( bool WXUNUSED(show
= true) ) { return false; }
1507 if (m_tabs
->IsFrozen() || m_tabs
->GetParent()->IsFrozen())
1510 m_tab_rect
= wxRect(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tabCtrlHeight
);
1511 if (m_tabs
->GetFlags() & wxAUI_NB_BOTTOM
)
1513 m_tab_rect
= wxRect (m_rect
.x
, m_rect
.y
+ m_rect
.height
- m_tabCtrlHeight
, m_rect
.width
, m_tabCtrlHeight
);
1514 m_tabs
->SetSize (m_rect
.x
, m_rect
.y
+ m_rect
.height
- m_tabCtrlHeight
, m_rect
.width
, m_tabCtrlHeight
);
1515 m_tabs
->SetRect (wxRect(0, 0, m_rect
.width
, m_tabCtrlHeight
));
1517 else //TODO: if (GetFlags() & wxAUI_NB_TOP)
1519 m_tab_rect
= wxRect (m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tabCtrlHeight
);
1520 m_tabs
->SetSize (m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tabCtrlHeight
);
1521 m_tabs
->SetRect (wxRect(0, 0, m_rect
.width
, m_tabCtrlHeight
));
1523 // TODO: else if (GetFlags() & wxAUI_NB_LEFT){}
1524 // TODO: else if (GetFlags() & wxAUI_NB_RIGHT){}
1529 wxAuiNotebookPageArray
& pages
= m_tabs
->GetPages();
1530 size_t i
, page_count
= pages
.GetCount();
1532 for (i
= 0; i
< page_count
; ++i
)
1534 int height
= m_rect
.height
- m_tabCtrlHeight
;
1537 // avoid passing negative height to wxWindow::SetSize(), this
1538 // results in assert failures/GTK+ warnings
1542 wxAuiNotebookPage
& page
= pages
.Item(i
);
1543 if (m_tabs
->GetFlags() & wxAUI_NB_BOTTOM
)
1545 page
.window
->SetSize(m_rect
.x
, m_rect
.y
, m_rect
.width
, height
);
1547 else //TODO: if (GetFlags() & wxAUI_NB_TOP)
1549 page
.window
->SetSize(m_rect
.x
, m_rect
.y
+ m_tabCtrlHeight
,
1550 m_rect
.width
, height
);
1552 // TODO: else if (GetFlags() & wxAUI_NB_LEFT){}
1553 // TODO: else if (GetFlags() & wxAUI_NB_RIGHT){}
1556 if (page
.window
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
1558 wxAuiMDIChildFrame
* wnd
= (wxAuiMDIChildFrame
*)page
.window
;
1559 wnd
->ApplyMDIChildFrameRect();
1566 void DoGetSize(int* x
, int* y
) const
1569 *x
= m_rect
.GetWidth();
1571 *y
= m_rect
.GetHeight();
1582 wxAuiTabCtrl
* m_tabs
;
1583 int m_tabCtrlHeight
;
1587 const int wxAuiBaseTabCtrlId
= 5380;
1590 // -- wxAuiNotebook class implementation --
1592 #define EVT_AUI_RANGE(id1, id2, event, func) \
1593 wx__DECLARE_EVT2(event, id1, id2, wxAuiNotebookEventHandler(func))
1595 BEGIN_EVENT_TABLE(wxAuiNotebook
, wxControl
)
1596 EVT_SIZE(wxAuiNotebook::OnSize
)
1597 EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocusNotebook
)
1598 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1599 wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
,
1600 wxAuiNotebook::OnTabClicked
)
1601 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1602 wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
,
1603 wxAuiNotebook::OnTabBeginDrag
)
1604 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1605 wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
,
1606 wxAuiNotebook::OnTabEndDrag
)
1607 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1608 wxEVT_COMMAND_AUINOTEBOOK_CANCEL_DRAG
,
1609 wxAuiNotebook::OnTabCancelDrag
)
1610 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1611 wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
,
1612 wxAuiNotebook::OnTabDragMotion
)
1613 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1614 wxEVT_COMMAND_AUINOTEBOOK_BUTTON
,
1615 wxAuiNotebook::OnTabButton
)
1616 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1617 wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
,
1618 wxAuiNotebook::OnTabMiddleDown
)
1619 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1620 wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
,
1621 wxAuiNotebook::OnTabMiddleUp
)
1622 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1623 wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
,
1624 wxAuiNotebook::OnTabRightDown
)
1625 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1626 wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
,
1627 wxAuiNotebook::OnTabRightUp
)
1628 EVT_AUI_RANGE(wxAuiBaseTabCtrlId
, wxAuiBaseTabCtrlId
+500,
1629 wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
,
1630 wxAuiNotebook::OnTabBgDClick
)
1631 EVT_NAVIGATION_KEY(wxAuiNotebook::OnNavigationKeyNotebook
)
1634 void wxAuiNotebook::Init()
1637 m_tabIdCounter
= wxAuiBaseTabCtrlId
;
1639 m_tabCtrlHeight
= 20;
1640 m_requestedBmpSize
= wxDefaultSize
;
1641 m_requestedTabCtrlHeight
= -1;
1644 bool wxAuiNotebook::Create(wxWindow
* parent
,
1650 if (!wxControl::Create(parent
, id
, pos
, size
, style
))
1653 InitNotebook(style
);
1658 // InitNotebook() contains common initialization
1659 // code called by all constructors
1660 void wxAuiNotebook::InitNotebook(long style
)
1662 SetName(wxT("wxAuiNotebook"));
1664 m_tabIdCounter
= wxAuiBaseTabCtrlId
;
1666 m_flags
= (unsigned int)style
;
1667 m_tabCtrlHeight
= 20;
1669 m_normalFont
= *wxNORMAL_FONT
;
1670 m_selectedFont
= *wxNORMAL_FONT
;
1671 m_selectedFont
.SetWeight(wxBOLD
);
1673 SetArtProvider(new wxAuiDefaultTabArt
);
1675 m_dummyWnd
= new wxWindow(this, wxID_ANY
, wxPoint(0,0), wxSize(0,0));
1676 m_dummyWnd
->SetSize(200, 200);
1677 m_dummyWnd
->Show(false);
1679 m_mgr
.SetManagedWindow(this);
1680 m_mgr
.SetFlags(wxAUI_MGR_DEFAULT
);
1681 m_mgr
.SetDockSizeConstraint(1.0, 1.0); // no dock size constraint
1683 m_mgr
.AddPane(m_dummyWnd
,
1684 wxAuiPaneInfo().Name(wxT("dummy")).Bottom().CaptionVisible(false).Show(false));
1689 wxAuiNotebook::~wxAuiNotebook()
1691 // Indicate we're deleting pages
1694 while ( GetPageCount() > 0 )
1700 void wxAuiNotebook::SetArtProvider(wxAuiTabArt
* art
)
1702 m_tabs
.SetArtProvider(art
);
1704 // Update the height and do nothing else if it did something but otherwise
1705 // (i.e. if the new art provider uses the same height as the old one) we
1706 // need to manually set the art provider for all tabs ourselves.
1707 if ( !UpdateTabCtrlHeight() )
1709 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1710 const size_t pane_count
= all_panes
.GetCount();
1711 for (size_t i
= 0; i
< pane_count
; ++i
)
1713 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
1714 if (pane
.name
== wxT("dummy"))
1716 wxTabFrame
* tab_frame
= (wxTabFrame
*)pane
.window
;
1717 wxAuiTabCtrl
* tabctrl
= tab_frame
->m_tabs
;
1718 tabctrl
->SetArtProvider(art
->Clone());
1723 // SetTabCtrlHeight() is the highest-level override of the
1724 // tab height. A call to this function effectively enforces a
1725 // specified tab ctrl height, overriding all other considerations,
1726 // such as text or bitmap height. It overrides any call to
1727 // SetUniformBitmapSize(). Specifying a height of -1 reverts
1728 // any previous call and returns to the default behaviour
1730 void wxAuiNotebook::SetTabCtrlHeight(int height
)
1732 m_requestedTabCtrlHeight
= height
;
1734 // if window is already initialized, recalculate the tab height
1737 UpdateTabCtrlHeight();
1742 // SetUniformBitmapSize() ensures that all tabs will have
1743 // the same height, even if some tabs don't have bitmaps
1744 // Passing wxDefaultSize to this function will instruct
1745 // the control to use dynamic tab height-- so when a tab
1746 // with a large bitmap is added, the tab ctrl's height will
1747 // automatically increase to accommodate the bitmap
1749 void wxAuiNotebook::SetUniformBitmapSize(const wxSize
& size
)
1751 m_requestedBmpSize
= size
;
1753 // if window is already initialized, recalculate the tab height
1756 UpdateTabCtrlHeight();
1760 // UpdateTabCtrlHeight() does the actual tab resizing. It's meant
1761 // to be used internally
1762 bool wxAuiNotebook::UpdateTabCtrlHeight()
1764 // get the tab ctrl height we will use
1765 int height
= CalculateTabCtrlHeight();
1767 // if the tab control height needs to change, update
1768 // all of our tab controls with the new height
1769 if (m_tabCtrlHeight
== height
)
1772 wxAuiTabArt
* art
= m_tabs
.GetArtProvider();
1774 m_tabCtrlHeight
= height
;
1776 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1777 size_t i
, pane_count
= all_panes
.GetCount();
1778 for (i
= 0; i
< pane_count
; ++i
)
1780 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
1781 if (pane
.name
== wxT("dummy"))
1783 wxTabFrame
* tab_frame
= (wxTabFrame
*)pane
.window
;
1784 wxAuiTabCtrl
* tabctrl
= tab_frame
->m_tabs
;
1785 tab_frame
->SetTabCtrlHeight(m_tabCtrlHeight
);
1786 tabctrl
->SetArtProvider(art
->Clone());
1787 tab_frame
->DoSizing();
1793 void wxAuiNotebook::UpdateHintWindowSize()
1795 wxSize size
= CalculateNewSplitSize();
1797 // the placeholder hint window should be set to this size
1798 wxAuiPaneInfo
& info
= m_mgr
.GetPane(wxT("dummy"));
1802 info
.BestSize(size
);
1803 m_dummyWnd
->SetSize(size
);
1808 // calculates the size of the new split
1809 wxSize
wxAuiNotebook::CalculateNewSplitSize()
1811 // count number of tab controls
1812 int tab_ctrl_count
= 0;
1813 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1814 size_t i
, pane_count
= all_panes
.GetCount();
1815 for (i
= 0; i
< pane_count
; ++i
)
1817 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
1818 if (pane
.name
== wxT("dummy"))
1823 wxSize new_split_size
;
1825 // if there is only one tab control, the first split
1826 // should happen around the middle
1827 if (tab_ctrl_count
< 2)
1829 new_split_size
= GetClientSize();
1830 new_split_size
.x
/= 2;
1831 new_split_size
.y
/= 2;
1835 // this is in place of a more complicated calculation
1836 // that needs to be implemented
1837 new_split_size
= wxSize(180,180);
1840 return new_split_size
;
1843 int wxAuiNotebook::CalculateTabCtrlHeight()
1845 // if a fixed tab ctrl height is specified,
1846 // just return that instead of calculating a
1848 if (m_requestedTabCtrlHeight
!= -1)
1849 return m_requestedTabCtrlHeight
;
1851 // find out new best tab height
1852 wxAuiTabArt
* art
= m_tabs
.GetArtProvider();
1854 return art
->GetBestTabCtrlSize(this,
1856 m_requestedBmpSize
);
1860 wxAuiTabArt
* wxAuiNotebook::GetArtProvider() const
1862 return m_tabs
.GetArtProvider();
1865 void wxAuiNotebook::SetWindowStyleFlag(long style
)
1867 wxControl::SetWindowStyleFlag(style
);
1869 m_flags
= (unsigned int)style
;
1871 // if the control is already initialized
1872 if (m_mgr
.GetManagedWindow() == (wxWindow
*)this)
1874 // let all of the tab children know about the new style
1876 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1877 size_t i
, pane_count
= all_panes
.GetCount();
1878 for (i
= 0; i
< pane_count
; ++i
)
1880 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
1881 if (pane
.name
== wxT("dummy"))
1883 wxTabFrame
* tabframe
= (wxTabFrame
*)pane
.window
;
1884 wxAuiTabCtrl
* tabctrl
= tabframe
->m_tabs
;
1885 tabctrl
->SetFlags(m_flags
);
1886 tabframe
->DoSizing();
1894 bool wxAuiNotebook::AddPage(wxWindow
* page
,
1895 const wxString
& caption
,
1897 const wxBitmap
& bitmap
)
1899 return InsertPage(GetPageCount(), page
, caption
, select
, bitmap
);
1902 bool wxAuiNotebook::InsertPage(size_t page_idx
,
1904 const wxString
& caption
,
1906 const wxBitmap
& bitmap
)
1908 wxASSERT_MSG(page
, wxT("page pointer must be non-NULL"));
1912 page
->Reparent(this);
1914 wxAuiNotebookPage info
;
1916 info
.caption
= caption
;
1917 info
.bitmap
= bitmap
;
1918 info
.active
= false;
1920 // if there are currently no tabs, the first added
1921 // tab must be active
1922 if (m_tabs
.GetPageCount() == 0)
1925 m_tabs
.InsertPage(page
, info
, page_idx
);
1927 // if that was the first page added, even if
1928 // select is false, it must become the "current page"
1929 // (though no select events will be fired)
1930 if (!select
&& m_tabs
.GetPageCount() == 1)
1932 //m_curPage = GetPageIndex(page);
1934 wxAuiTabCtrl
* active_tabctrl
= GetActiveTabCtrl();
1935 if (page_idx
>= active_tabctrl
->GetPageCount())
1936 active_tabctrl
->AddPage(page
, info
);
1938 active_tabctrl
->InsertPage(page
, info
, page_idx
);
1940 UpdateTabCtrlHeight();
1942 active_tabctrl
->DoShowHide();
1944 // adjust selected index
1945 if(m_curPage
>= (int) page_idx
)
1950 SetSelectionToWindow(page
);
1957 // DeletePage() removes a tab from the multi-notebook,
1958 // and destroys the window as well
1959 bool wxAuiNotebook::DeletePage(size_t page_idx
)
1961 if (page_idx
>= m_tabs
.GetPageCount())
1964 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
1966 // hide the window in advance, as this will
1968 ShowWnd(wnd
, false);
1970 if (!RemovePage(page_idx
))
1974 // actually destroy the window now
1975 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
1977 // delete the child frame with pending delete, as is
1978 // customary with frame windows
1979 if (!wxPendingDelete
.Member(wnd
))
1980 wxPendingDelete
.Append(wnd
);
1993 // RemovePage() removes a tab from the multi-notebook,
1994 // but does not destroy the window
1995 bool wxAuiNotebook::RemovePage(size_t page_idx
)
1997 // save active window pointer
1998 wxWindow
* active_wnd
= NULL
;
2000 active_wnd
= m_tabs
.GetWindowFromIdx(m_curPage
);
2002 // save pointer of window being deleted
2003 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
2004 wxWindow
* new_active
= NULL
;
2006 // make sure we found the page
2010 // find out which onscreen tab ctrl owns this tab
2013 if (!FindTab(wnd
, &ctrl
, &ctrl_idx
))
2016 bool is_curpage
= (m_curPage
== (int)page_idx
);
2017 bool is_active_in_split
= ctrl
->GetPage(ctrl_idx
).active
;
2020 // remove the tab from main catalog
2021 if (!m_tabs
.RemovePage(wnd
))
2024 // remove the tab from the onscreen tab ctrl
2025 ctrl
->RemovePage(wnd
);
2027 if (is_active_in_split
)
2029 int ctrl_new_page_count
= (int)ctrl
->GetPageCount();
2031 if (ctrl_idx
>= ctrl_new_page_count
)
2032 ctrl_idx
= ctrl_new_page_count
-1;
2034 if (ctrl_idx
>= 0 && ctrl_idx
< (int)ctrl
->GetPageCount())
2036 // set new page as active in the tab split
2037 ctrl
->SetActivePage(ctrl_idx
);
2039 // if the page deleted was the current page for the
2040 // entire tab control, then record the window
2041 // pointer of the new active page for activation
2044 new_active
= ctrl
->GetWindowFromIdx(ctrl_idx
);
2050 // we are not deleting the active page, so keep it the same
2051 new_active
= active_wnd
;
2057 // we haven't yet found a new page to active,
2058 // so select the next page from the main tab
2061 if (page_idx
< m_tabs
.GetPageCount())
2063 new_active
= m_tabs
.GetPage(page_idx
).window
;
2066 if (!new_active
&& m_tabs
.GetPageCount() > 0)
2068 new_active
= m_tabs
.GetPage(0).window
;
2073 RemoveEmptyTabFrames();
2075 m_curPage
= wxNOT_FOUND
;
2077 // set new active pane unless we're being destroyed anyhow
2078 if (new_active
&& !m_isBeingDeleted
)
2079 SetSelectionToWindow(new_active
);
2084 // GetPageIndex() returns the index of the page, or -1 if the
2085 // page could not be located in the notebook
2086 int wxAuiNotebook::GetPageIndex(wxWindow
* page_wnd
) const
2088 return m_tabs
.GetIdxFromWindow(page_wnd
);
2093 // SetPageText() changes the tab caption of the specified page
2094 bool wxAuiNotebook::SetPageText(size_t page_idx
, const wxString
& text
)
2096 if (page_idx
>= m_tabs
.GetPageCount())
2099 // update our own tab catalog
2100 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2101 page_info
.caption
= text
;
2103 // update what's on screen
2106 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
2108 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
2109 info
.caption
= text
;
2117 // returns the page caption
2118 wxString
wxAuiNotebook::GetPageText(size_t page_idx
) const
2120 if (page_idx
>= m_tabs
.GetPageCount())
2121 return wxEmptyString
;
2123 // update our own tab catalog
2124 const wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2125 return page_info
.caption
;
2128 bool wxAuiNotebook::SetPageBitmap(size_t page_idx
, const wxBitmap
& bitmap
)
2130 if (page_idx
>= m_tabs
.GetPageCount())
2133 // update our own tab catalog
2134 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2135 page_info
.bitmap
= bitmap
;
2137 // tab height might have changed
2138 UpdateTabCtrlHeight();
2140 // update what's on screen
2143 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
2145 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
2146 info
.bitmap
= bitmap
;
2154 // returns the page bitmap
2155 wxBitmap
wxAuiNotebook::GetPageBitmap(size_t page_idx
) const
2157 if (page_idx
>= m_tabs
.GetPageCount())
2160 // update our own tab catalog
2161 const wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2162 return page_info
.bitmap
;
2165 // GetSelection() returns the index of the currently active page
2166 int wxAuiNotebook::GetSelection() const
2171 // SetSelection() sets the currently active page
2172 int wxAuiNotebook::SetSelection(size_t new_page
)
2174 return DoModifySelection(new_page
, true);
2177 void wxAuiNotebook::SetSelectionToWindow(wxWindow
*win
)
2179 const int idx
= m_tabs
.GetIdxFromWindow(win
);
2180 wxCHECK_RET( idx
!= wxNOT_FOUND
, wxT("invalid notebook page") );
2183 // since a tab was clicked, let the parent know that we received
2184 // the focus, even if we will assign that focus immediately
2185 // to the child tab in the SetSelection call below
2186 // (the child focus event will also let wxAuiManager, if any,
2187 // know that the notebook control has been activated)
2189 wxWindow
* parent
= GetParent();
2192 wxChildFocusEvent
eventFocus(this);
2193 parent
->GetEventHandler()->ProcessEvent(eventFocus
);
2200 // GetPageCount() returns the total number of
2201 // pages managed by the multi-notebook
2202 size_t wxAuiNotebook::GetPageCount() const
2204 return m_tabs
.GetPageCount();
2207 // GetPage() returns the wxWindow pointer of the
2209 wxWindow
* wxAuiNotebook::GetPage(size_t page_idx
) const
2211 wxASSERT(page_idx
< m_tabs
.GetPageCount());
2213 return m_tabs
.GetWindowFromIdx(page_idx
);
2216 // DoSizing() performs all sizing operations in each tab control
2217 void wxAuiNotebook::DoSizing()
2219 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2220 size_t i
, pane_count
= all_panes
.GetCount();
2221 for (i
= 0; i
< pane_count
; ++i
)
2223 if (all_panes
.Item(i
).name
== wxT("dummy"))
2226 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2227 tabframe
->DoSizing();
2231 // GetActiveTabCtrl() returns the active tab control. It is
2232 // called to determine which control gets new windows being added
2233 wxAuiTabCtrl
* wxAuiNotebook::GetActiveTabCtrl()
2235 if (m_curPage
>= 0 && m_curPage
< (int)m_tabs
.GetPageCount())
2240 // find the tab ctrl with the current page
2241 if (FindTab(m_tabs
.GetPage(m_curPage
).window
,
2248 // no current page, just find the first tab ctrl
2249 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2250 size_t i
, pane_count
= all_panes
.GetCount();
2251 for (i
= 0; i
< pane_count
; ++i
)
2253 if (all_panes
.Item(i
).name
== wxT("dummy"))
2256 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2257 return tabframe
->m_tabs
;
2260 // If there is no tabframe at all, create one
2261 wxTabFrame
* tabframe
= new wxTabFrame
;
2262 tabframe
->SetTabCtrlHeight(m_tabCtrlHeight
);
2263 tabframe
->m_tabs
= new wxAuiTabCtrl(this,
2267 wxNO_BORDER
|wxWANTS_CHARS
);
2268 tabframe
->m_tabs
->SetFlags(m_flags
);
2269 tabframe
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
2270 m_mgr
.AddPane(tabframe
,
2271 wxAuiPaneInfo().Center().CaptionVisible(false));
2275 return tabframe
->m_tabs
;
2278 // FindTab() finds the tab control that currently contains the window as well
2279 // as the index of the window in the tab control. It returns true if the
2280 // window was found, otherwise false.
2281 bool wxAuiNotebook::FindTab(wxWindow
* page
, wxAuiTabCtrl
** ctrl
, int* idx
)
2283 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2284 size_t i
, pane_count
= all_panes
.GetCount();
2285 for (i
= 0; i
< pane_count
; ++i
)
2287 if (all_panes
.Item(i
).name
== wxT("dummy"))
2290 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2292 int page_idx
= tabframe
->m_tabs
->GetIdxFromWindow(page
);
2295 *ctrl
= tabframe
->m_tabs
;
2304 void wxAuiNotebook::Split(size_t page
, int direction
)
2306 wxSize cli_size
= GetClientSize();
2308 // get the page's window pointer
2309 wxWindow
* wnd
= GetPage(page
);
2313 // notebooks with 1 or less pages can't be split
2314 if (GetPageCount() < 2)
2317 // find out which tab control the page currently belongs to
2318 wxAuiTabCtrl
*src_tabs
, *dest_tabs
;
2321 if (!FindTab(wnd
, &src_tabs
, &src_idx
))
2323 if (!src_tabs
|| src_idx
== -1)
2326 // choose a split size
2328 if (GetPageCount() > 2)
2330 split_size
= CalculateNewSplitSize();
2334 // because there are two panes, always split them
2336 split_size
= GetClientSize();
2342 // create a new tab frame
2343 wxTabFrame
* new_tabs
= new wxTabFrame
;
2344 new_tabs
->m_rect
= wxRect(wxPoint(0,0), split_size
);
2345 new_tabs
->SetTabCtrlHeight(m_tabCtrlHeight
);
2346 new_tabs
->m_tabs
= new wxAuiTabCtrl(this,
2350 wxNO_BORDER
|wxWANTS_CHARS
);
2351 new_tabs
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
2352 new_tabs
->m_tabs
->SetFlags(m_flags
);
2353 dest_tabs
= new_tabs
->m_tabs
;
2355 // create a pane info structure with the information
2356 // about where the pane should be added
2357 wxAuiPaneInfo paneInfo
= wxAuiPaneInfo().Bottom().CaptionVisible(false);
2360 if (direction
== wxLEFT
)
2363 mouse_pt
= wxPoint(0, cli_size
.y
/2);
2365 else if (direction
== wxRIGHT
)
2368 mouse_pt
= wxPoint(cli_size
.x
, cli_size
.y
/2);
2370 else if (direction
== wxTOP
)
2373 mouse_pt
= wxPoint(cli_size
.x
/2, 0);
2375 else if (direction
== wxBOTTOM
)
2378 mouse_pt
= wxPoint(cli_size
.x
/2, cli_size
.y
);
2381 m_mgr
.AddPane(new_tabs
, paneInfo
, mouse_pt
);
2384 // remove the page from the source tabs
2385 wxAuiNotebookPage page_info
= src_tabs
->GetPage(src_idx
);
2386 page_info
.active
= false;
2387 src_tabs
->RemovePage(page_info
.window
);
2388 if (src_tabs
->GetPageCount() > 0)
2390 src_tabs
->SetActivePage((size_t)0);
2391 src_tabs
->DoShowHide();
2392 src_tabs
->Refresh();
2396 // add the page to the destination tabs
2397 dest_tabs
->InsertPage(page_info
.window
, page_info
, 0);
2399 if (src_tabs
->GetPageCount() == 0)
2401 RemoveEmptyTabFrames();
2405 dest_tabs
->DoShowHide();
2406 dest_tabs
->Refresh();
2408 // force the set selection function reset the selection
2411 // set the active page to the one we just split off
2412 SetSelectionToPage(page_info
);
2414 UpdateHintWindowSize();
2418 void wxAuiNotebook::OnSize(wxSizeEvent
& evt
)
2420 UpdateHintWindowSize();
2425 void wxAuiNotebook::OnTabClicked(wxAuiNotebookEvent
& evt
)
2427 wxAuiTabCtrl
* ctrl
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2428 wxASSERT(ctrl
!= NULL
);
2430 wxWindow
* wnd
= ctrl
->GetWindowFromIdx(evt
.GetSelection());
2431 wxASSERT(wnd
!= NULL
);
2433 SetSelectionToWindow(wnd
);
2436 void wxAuiNotebook::OnTabBgDClick(wxAuiNotebookEvent
& WXUNUSED(evt
))
2438 // notify owner that the tabbar background has been double-clicked
2439 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_BG_DCLICK
, m_windowId
);
2440 e
.SetEventObject(this);
2441 GetEventHandler()->ProcessEvent(e
);
2444 void wxAuiNotebook::OnTabBeginDrag(wxAuiNotebookEvent
&)
2449 void wxAuiNotebook::OnTabDragMotion(wxAuiNotebookEvent
& evt
)
2451 wxPoint screen_pt
= ::wxGetMousePosition();
2452 wxPoint client_pt
= ScreenToClient(screen_pt
);
2455 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2456 wxAuiTabCtrl
* dest_tabs
= GetTabCtrlFromPoint(client_pt
);
2458 if (dest_tabs
== src_tabs
)
2462 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
2465 // always hide the hint for inner-tabctrl drag
2468 // if tab moving is not allowed, leave
2469 if (!(m_flags
& wxAUI_NB_TAB_MOVE
))
2474 wxPoint pt
= dest_tabs
->ScreenToClient(screen_pt
);
2475 wxWindow
* dest_location_tab
;
2477 // this is an inner-tab drag/reposition
2478 if (dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &dest_location_tab
))
2480 int src_idx
= evt
.GetSelection();
2481 int dest_idx
= dest_tabs
->GetIdxFromWindow(dest_location_tab
);
2483 // prevent jumpy drag
2484 if ((src_idx
== dest_idx
) || dest_idx
== -1 ||
2485 (src_idx
> dest_idx
&& m_lastDragX
<= pt
.x
) ||
2486 (src_idx
< dest_idx
&& m_lastDragX
>= pt
.x
))
2493 wxWindow
* src_tab
= dest_tabs
->GetWindowFromIdx(src_idx
);
2494 dest_tabs
->MovePage(src_tab
, dest_idx
);
2495 dest_tabs
->SetActivePage((size_t)dest_idx
);
2496 dest_tabs
->DoShowHide();
2497 dest_tabs
->Refresh();
2506 // if external drag is allowed, check if the tab is being dragged
2507 // over a different wxAuiNotebook control
2508 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
2510 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(screen_pt
);
2512 // if we aren't over any window, stop here
2516 // make sure we are not over the hint window
2517 if (!tab_ctrl
->IsKindOf(CLASSINFO(wxFrame
)))
2521 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
2523 tab_ctrl
= tab_ctrl
->GetParent();
2528 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
2532 wxRect hint_rect
= tab_ctrl
->GetClientRect();
2533 tab_ctrl
->ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
2534 m_mgr
.ShowHint(hint_rect
);
2543 // we are either over a hint window, or not over a tab
2544 // window, and there is no where to drag to, so exit
2551 // if there are less than two panes, split can't happen, so leave
2552 if (m_tabs
.GetPageCount() < 2)
2555 // if tab moving is not allowed, leave
2556 if (!(m_flags
& wxAUI_NB_TAB_SPLIT
))
2562 src_tabs
->SetCursor(wxCursor(wxCURSOR_SIZING
));
2568 wxRect hint_rect
= dest_tabs
->GetRect();
2569 ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
2570 m_mgr
.ShowHint(hint_rect
);
2574 m_mgr
.DrawHintRect(m_dummyWnd
, client_pt
, zero
);
2580 void wxAuiNotebook::OnTabEndDrag(wxAuiNotebookEvent
& evt
)
2585 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2586 wxCHECK_RET( src_tabs
, wxT("no source object?") );
2588 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
2590 // get the mouse position, which will be used to determine the drop point
2591 wxPoint mouse_screen_pt
= ::wxGetMousePosition();
2592 wxPoint mouse_client_pt
= ScreenToClient(mouse_screen_pt
);
2596 // check for an external move
2597 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
2599 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(mouse_screen_pt
);
2603 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
2605 tab_ctrl
= tab_ctrl
->GetParent();
2610 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
2614 // find out from the destination control
2615 // if it's ok to drop this tab here
2616 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
, m_windowId
);
2617 e
.SetSelection(evt
.GetSelection());
2618 e
.SetOldSelection(evt
.GetSelection());
2619 e
.SetEventObject(this);
2620 e
.SetDragSource(this);
2621 e
.Veto(); // dropping must be explicitly approved by control owner
2623 nb
->GetEventHandler()->ProcessEvent(e
);
2627 // no answer or negative answer
2633 int src_idx
= evt
.GetSelection();
2634 wxWindow
* src_page
= src_tabs
->GetWindowFromIdx(src_idx
);
2636 // Check that it's not an impossible parent relationship
2638 while (p
&& !p
->IsTopLevel())
2647 // get main index of the page
2648 int main_idx
= m_tabs
.GetIdxFromWindow(src_page
);
2649 wxCHECK_RET( main_idx
!= wxNOT_FOUND
, wxT("no source page?") );
2652 // make a copy of the page info
2653 wxAuiNotebookPage page_info
= m_tabs
.GetPage(main_idx
);
2655 // remove the page from the source notebook
2656 RemovePage(main_idx
);
2658 // reparent the page
2659 src_page
->Reparent(nb
);
2662 // found out the insert idx
2663 wxAuiTabCtrl
* dest_tabs
= (wxAuiTabCtrl
*)tab_ctrl
;
2664 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
2666 wxWindow
* target
= NULL
;
2667 int insert_idx
= -1;
2668 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
2671 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
2675 // add the page to the new notebook
2676 if (insert_idx
== -1)
2677 insert_idx
= dest_tabs
->GetPageCount();
2678 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
2679 nb
->m_tabs
.AddPage(page_info
.window
, page_info
);
2682 dest_tabs
->DoShowHide();
2683 dest_tabs
->Refresh();
2685 // set the selection in the destination tab control
2686 nb
->SetSelectionToPage(page_info
);
2688 // notify owner that the tab has been dragged
2689 wxAuiNotebookEvent
e2(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE
, m_windowId
);
2690 e2
.SetSelection(evt
.GetSelection());
2691 e2
.SetOldSelection(evt
.GetSelection());
2692 e2
.SetEventObject(this);
2693 GetEventHandler()->ProcessEvent(e2
);
2703 // only perform a tab split if it's allowed
2704 wxAuiTabCtrl
* dest_tabs
= NULL
;
2706 if ((m_flags
& wxAUI_NB_TAB_SPLIT
) && m_tabs
.GetPageCount() >= 2)
2708 // If the pointer is in an existing tab frame, do a tab insert
2709 wxWindow
* hit_wnd
= ::wxFindWindowAtPoint(mouse_screen_pt
);
2710 wxTabFrame
* tab_frame
= (wxTabFrame
*)GetTabFrameFromTabCtrl(hit_wnd
);
2711 int insert_idx
= -1;
2714 dest_tabs
= tab_frame
->m_tabs
;
2716 if (dest_tabs
== src_tabs
)
2720 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
2721 wxWindow
* target
= NULL
;
2722 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
2725 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
2731 wxRect rect
= m_mgr
.CalculateHintRect(m_dummyWnd
,
2736 // there is no suitable drop location here, exit out
2740 // If there is no tabframe at all, create one
2741 wxTabFrame
* new_tabs
= new wxTabFrame
;
2742 new_tabs
->m_rect
= wxRect(wxPoint(0,0), CalculateNewSplitSize());
2743 new_tabs
->SetTabCtrlHeight(m_tabCtrlHeight
);
2744 new_tabs
->m_tabs
= new wxAuiTabCtrl(this,
2748 wxNO_BORDER
|wxWANTS_CHARS
);
2749 new_tabs
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
2750 new_tabs
->m_tabs
->SetFlags(m_flags
);
2752 m_mgr
.AddPane(new_tabs
,
2753 wxAuiPaneInfo().Bottom().CaptionVisible(false),
2756 dest_tabs
= new_tabs
->m_tabs
;
2761 // remove the page from the source tabs
2762 wxAuiNotebookPage page_info
= src_tabs
->GetPage(evt
.GetSelection());
2763 page_info
.active
= false;
2764 src_tabs
->RemovePage(page_info
.window
);
2765 if (src_tabs
->GetPageCount() > 0)
2767 src_tabs
->SetActivePage((size_t)0);
2768 src_tabs
->DoShowHide();
2769 src_tabs
->Refresh();
2774 // add the page to the destination tabs
2775 if (insert_idx
== -1)
2776 insert_idx
= dest_tabs
->GetPageCount();
2777 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
2779 if (src_tabs
->GetPageCount() == 0)
2781 RemoveEmptyTabFrames();
2785 dest_tabs
->DoShowHide();
2786 dest_tabs
->Refresh();
2788 // force the set selection function reset the selection
2791 // set the active page to the one we just split off
2792 SetSelectionToPage(page_info
);
2794 UpdateHintWindowSize();
2797 // notify owner that the tab has been dragged
2798 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_DRAG_DONE
, m_windowId
);
2799 e
.SetSelection(evt
.GetSelection());
2800 e
.SetOldSelection(evt
.GetSelection());
2801 e
.SetEventObject(this);
2802 GetEventHandler()->ProcessEvent(e
);
2807 void wxAuiNotebook::OnTabCancelDrag(wxAuiNotebookEvent
& command_evt
)
2809 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
2813 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2814 wxCHECK_RET( src_tabs
, wxT("no source object?") );
2816 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
2819 wxAuiTabCtrl
* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint
& pt
)
2821 // if we've just removed the last tab from the source
2822 // tab set, the remove the tab control completely
2823 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2824 size_t i
, pane_count
= all_panes
.GetCount();
2825 for (i
= 0; i
< pane_count
; ++i
)
2827 if (all_panes
.Item(i
).name
== wxT("dummy"))
2830 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2831 if (tabframe
->m_tab_rect
.Contains(pt
))
2832 return tabframe
->m_tabs
;
2838 wxWindow
* wxAuiNotebook::GetTabFrameFromTabCtrl(wxWindow
* tab_ctrl
)
2840 // if we've just removed the last tab from the source
2841 // tab set, the remove the tab control completely
2842 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2843 size_t i
, pane_count
= all_panes
.GetCount();
2844 for (i
= 0; i
< pane_count
; ++i
)
2846 if (all_panes
.Item(i
).name
== wxT("dummy"))
2849 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2850 if (tabframe
->m_tabs
== tab_ctrl
)
2859 void wxAuiNotebook::RemoveEmptyTabFrames()
2861 // if we've just removed the last tab from the source
2862 // tab set, the remove the tab control completely
2863 wxAuiPaneInfoArray all_panes
= m_mgr
.GetAllPanes();
2864 size_t i
, pane_count
= all_panes
.GetCount();
2865 for (i
= 0; i
< pane_count
; ++i
)
2867 if (all_panes
.Item(i
).name
== wxT("dummy"))
2870 wxTabFrame
* tab_frame
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2871 if (tab_frame
->m_tabs
->GetPageCount() == 0)
2873 m_mgr
.DetachPane(tab_frame
);
2875 // use pending delete because sometimes during
2876 // window closing, refreshs are pending
2877 if (!wxPendingDelete
.Member(tab_frame
->m_tabs
))
2878 wxPendingDelete
.Append(tab_frame
->m_tabs
);
2880 tab_frame
->m_tabs
= NULL
;
2887 // check to see if there is still a center pane;
2888 // if there isn't, make a frame the center pane
2889 wxAuiPaneInfoArray panes
= m_mgr
.GetAllPanes();
2890 pane_count
= panes
.GetCount();
2891 wxWindow
* first_good
= NULL
;
2892 bool center_found
= false;
2893 for (i
= 0; i
< pane_count
; ++i
)
2895 if (panes
.Item(i
).name
== wxT("dummy"))
2897 if (panes
.Item(i
).dock_direction
== wxAUI_DOCK_CENTRE
)
2898 center_found
= true;
2900 first_good
= panes
.Item(i
).window
;
2903 if (!center_found
&& first_good
)
2905 m_mgr
.GetPane(first_good
).Centre();
2908 if (!m_isBeingDeleted
)
2912 void wxAuiNotebook::OnChildFocusNotebook(wxChildFocusEvent
& evt
)
2916 // if we're dragging a tab, don't change the current selection.
2917 // This code prevents a bug that used to happen when the hint window
2918 // was hidden. In the bug, the focus would return to the notebook
2919 // child, which would then enter this handler and call
2920 // SetSelection, which is not desired turn tab dragging.
2922 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2923 size_t i
, pane_count
= all_panes
.GetCount();
2924 for (i
= 0; i
< pane_count
; ++i
)
2926 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2927 if (pane
.name
== wxT("dummy"))
2929 wxTabFrame
* tabframe
= (wxTabFrame
*)pane
.window
;
2930 if (tabframe
->m_tabs
->IsDragging())
2935 // change the tab selection to the child
2936 // which was focused
2937 int idx
= m_tabs
.GetIdxFromWindow(evt
.GetWindow());
2938 if (idx
!= -1 && idx
!= m_curPage
)
2944 void wxAuiNotebook::OnNavigationKeyNotebook(wxNavigationKeyEvent
& event
)
2946 if ( event
.IsWindowChange() ) {
2948 // FIXME: the problem with this is that if we have a split notebook,
2949 // we selection may go all over the place.
2950 AdvanceSelection(event
.GetDirection());
2953 // we get this event in 3 cases
2955 // a) one of our pages might have generated it because the user TABbed
2956 // out from it in which case we should propagate the event upwards and
2957 // our parent will take care of setting the focus to prev/next sibling
2961 // b) the parent panel wants to give the focus to us so that we
2962 // forward it to our selected page. We can't deal with this in
2963 // OnSetFocus() because we don't know which direction the focus came
2964 // from in this case and so can't choose between setting the focus to
2965 // first or last panel child
2969 // c) we ourselves (see MSWTranslateMessage) generated the event
2971 wxWindow
* const parent
= GetParent();
2973 // the wxObject* casts are required to avoid MinGW GCC 2.95.3 ICE
2974 const bool isFromParent
= event
.GetEventObject() == (wxObject
*) parent
;
2975 const bool isFromSelf
= event
.GetEventObject() == (wxObject
*) this;
2977 if ( isFromParent
|| isFromSelf
)
2979 // no, it doesn't come from child, case (b) or (c): forward to a
2980 // page but only if direction is backwards (TAB) or from ourselves,
2981 if ( GetSelection() != wxNOT_FOUND
&&
2982 (!event
.GetDirection() || isFromSelf
) )
2984 // so that the page knows that the event comes from it's parent
2985 // and is being propagated downwards
2986 event
.SetEventObject(this);
2988 wxWindow
*page
= GetPage(GetSelection());
2989 if ( !page
->GetEventHandler()->ProcessEvent(event
) )
2993 //else: page manages focus inside it itself
2995 else // otherwise set the focus to the notebook itself
3002 // it comes from our child, case (a), pass to the parent, but only
3003 // if the direction is forwards. Otherwise set the focus to the
3004 // notebook itself. The notebook is always the 'first' control of a
3006 if ( !event
.GetDirection() )
3012 event
.SetCurrentFocus(this);
3013 parent
->GetEventHandler()->ProcessEvent(event
);
3019 void wxAuiNotebook::OnTabButton(wxAuiNotebookEvent
& evt
)
3021 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3023 int button_id
= evt
.GetInt();
3025 if (button_id
== wxAUI_BUTTON_CLOSE
)
3027 int selection
= evt
.GetSelection();
3029 if (selection
== -1)
3031 // if the close button is to the right, use the active
3032 // page selection to determine which page to close
3033 selection
= tabs
->GetActivePage();
3036 if (selection
!= -1)
3038 wxWindow
* close_wnd
= tabs
->GetWindowFromIdx(selection
);
3040 // ask owner if it's ok to close the tab
3041 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
, m_windowId
);
3042 e
.SetSelection(m_tabs
.GetIdxFromWindow(close_wnd
));
3043 const int idx
= m_tabs
.GetIdxFromWindow(close_wnd
);
3044 e
.SetSelection(idx
);
3045 e
.SetOldSelection(evt
.GetSelection());
3046 e
.SetEventObject(this);
3047 GetEventHandler()->ProcessEvent(e
);
3053 if (close_wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
3060 int main_idx
= m_tabs
.GetIdxFromWindow(close_wnd
);
3061 wxCHECK_RET( main_idx
!= wxNOT_FOUND
, wxT("no page to delete?") );
3063 DeletePage(main_idx
);
3066 // notify owner that the tab has been closed
3067 wxAuiNotebookEvent
e2(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSED
, m_windowId
);
3068 e2
.SetSelection(idx
);
3069 e2
.SetEventObject(this);
3070 GetEventHandler()->ProcessEvent(e2
);
3076 void wxAuiNotebook::OnTabMiddleDown(wxAuiNotebookEvent
& evt
)
3078 // patch event through to owner
3079 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3080 wxWindow
* wnd
= tabs
->GetWindowFromIdx(evt
.GetSelection());
3082 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_DOWN
, m_windowId
);
3083 e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
));
3084 e
.SetEventObject(this);
3085 GetEventHandler()->ProcessEvent(e
);
3088 void wxAuiNotebook::OnTabMiddleUp(wxAuiNotebookEvent
& evt
)
3090 // if the wxAUI_NB_MIDDLE_CLICK_CLOSE is specified, middle
3091 // click should act like a tab close action. However, first
3092 // give the owner an opportunity to handle the middle up event
3093 // for custom action
3095 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3096 wxWindow
* wnd
= tabs
->GetWindowFromIdx(evt
.GetSelection());
3098 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_MIDDLE_UP
, m_windowId
);
3099 e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
));
3100 e
.SetEventObject(this);
3101 if (GetEventHandler()->ProcessEvent(e
))
3106 // check if we are supposed to close on middle-up
3107 if ((m_flags
& wxAUI_NB_MIDDLE_CLICK_CLOSE
) == 0)
3110 // simulate the user pressing the close button on the tab
3111 evt
.SetInt(wxAUI_BUTTON_CLOSE
);
3115 void wxAuiNotebook::OnTabRightDown(wxAuiNotebookEvent
& evt
)
3117 // patch event through to owner
3118 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3119 wxWindow
* wnd
= tabs
->GetWindowFromIdx(evt
.GetSelection());
3121 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_DOWN
, m_windowId
);
3122 e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
));
3123 e
.SetEventObject(this);
3124 GetEventHandler()->ProcessEvent(e
);
3127 void wxAuiNotebook::OnTabRightUp(wxAuiNotebookEvent
& evt
)
3129 // patch event through to owner
3130 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3131 wxWindow
* wnd
= tabs
->GetWindowFromIdx(evt
.GetSelection());
3133 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_TAB_RIGHT_UP
, m_windowId
);
3134 e
.SetSelection(m_tabs
.GetIdxFromWindow(wnd
));
3135 e
.SetEventObject(this);
3136 GetEventHandler()->ProcessEvent(e
);
3139 // Sets the normal font
3140 void wxAuiNotebook::SetNormalFont(const wxFont
& font
)
3142 m_normalFont
= font
;
3143 GetArtProvider()->SetNormalFont(font
);
3146 // Sets the selected tab font
3147 void wxAuiNotebook::SetSelectedFont(const wxFont
& font
)
3149 m_selectedFont
= font
;
3150 GetArtProvider()->SetSelectedFont(font
);
3153 // Sets the measuring font
3154 void wxAuiNotebook::SetMeasuringFont(const wxFont
& font
)
3156 GetArtProvider()->SetMeasuringFont(font
);
3159 // Sets the tab font
3160 bool wxAuiNotebook::SetFont(const wxFont
& font
)
3162 wxControl::SetFont(font
);
3164 wxFont
normalFont(font
);
3165 wxFont
selectedFont(normalFont
);
3166 selectedFont
.SetWeight(wxBOLD
);
3168 SetNormalFont(normalFont
);
3169 SetSelectedFont(selectedFont
);
3170 SetMeasuringFont(selectedFont
);
3175 // Gets the tab control height
3176 int wxAuiNotebook::GetTabCtrlHeight() const
3178 return m_tabCtrlHeight
;
3181 // Gets the height of the notebook for a given page height
3182 int wxAuiNotebook::GetHeightForPageHeight(int pageHeight
)
3184 UpdateTabCtrlHeight();
3186 int tabCtrlHeight
= GetTabCtrlHeight();
3187 int decorHeight
= 2;
3188 return tabCtrlHeight
+ pageHeight
+ decorHeight
;
3191 // Advances the selection, generation page selection events
3192 void wxAuiNotebook::AdvanceSelection(bool forward
)
3194 if (GetPageCount() <= 1)
3197 int currentSelection
= GetSelection();
3201 if (currentSelection
== (int) (GetPageCount() - 1))
3203 else if (currentSelection
== -1)
3204 currentSelection
= 0;
3206 currentSelection
++;
3210 if (currentSelection
<= 0)
3213 currentSelection
--;
3216 SetSelection(currentSelection
);
3219 // Shows the window menu
3220 bool wxAuiNotebook::ShowWindowMenu()
3222 wxAuiTabCtrl
* tabCtrl
= GetActiveTabCtrl();
3224 int idx
= tabCtrl
->GetArtProvider()->ShowDropDown(tabCtrl
, tabCtrl
->GetPages(), tabCtrl
->GetActivePage());
3228 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, tabCtrl
->GetId());
3229 e
.SetSelection(idx
);
3230 e
.SetOldSelection(tabCtrl
->GetActivePage());
3231 e
.SetEventObject(tabCtrl
);
3232 GetEventHandler()->ProcessEvent(e
);
3240 void wxAuiNotebook::Thaw()
3247 void wxAuiNotebook::SetPageSize (const wxSize
& WXUNUSED(size
))
3249 wxFAIL_MSG("Not implemented for wxAuiNotebook");
3252 int wxAuiNotebook::HitTest (const wxPoint
& WXUNUSED(pt
), long* WXUNUSED(flags
)) const
3254 wxFAIL_MSG("Not implemented for wxAuiNotebook");
3258 int wxAuiNotebook::GetPageImage(size_t WXUNUSED(n
)) const
3260 wxFAIL_MSG("Not implemented for wxAuiNotebook");
3264 bool wxAuiNotebook::SetPageImage(size_t n
, int imageId
)
3266 return SetPageBitmap(n
, GetImageList()->GetBitmap(imageId
));
3269 wxWindow
* wxAuiNotebook::GetCurrentPage () const
3271 const int sel
= GetSelection();
3273 return sel
== wxNOT_FOUND
? NULL
: GetPage(sel
);
3276 int wxAuiNotebook::ChangeSelection(size_t n
)
3278 return DoModifySelection(n
, false);
3281 bool wxAuiNotebook::AddPage(wxWindow
*page
, const wxString
&text
, bool select
,
3286 return AddPage(page
, text
, select
, GetImageList()->GetBitmap(imageId
));
3290 return AddPage(page
, text
, select
, wxNullBitmap
);
3294 bool wxAuiNotebook::DeleteAllPages()
3296 size_t count
= GetPageCount();
3297 for(size_t i
= 0; i
< count
; i
++)
3304 bool wxAuiNotebook::InsertPage(size_t index
, wxWindow
*page
,
3305 const wxString
&text
, bool select
,
3310 return InsertPage(index
, page
, text
, select
,
3311 GetImageList()->GetBitmap(imageId
));
3315 return InsertPage(index
, page
, text
, select
, wxNullBitmap
);
3319 int wxAuiNotebook::DoModifySelection(size_t n
, bool events
)
3321 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(n
);
3325 // don't change the page unless necessary;
3326 // however, clicking again on a tab should give it the focus.
3327 if ((int)n
== m_curPage
)
3331 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
3333 if (FindFocus() != ctrl
)
3339 bool vetoed
= false;
3341 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
3345 evt
.SetSelection(n
);
3346 evt
.SetOldSelection(m_curPage
);
3347 evt
.SetEventObject(this);
3348 GetEventHandler()->ProcessEvent(evt
);
3349 vetoed
= !evt
.IsAllowed();
3354 int old_curpage
= m_curPage
;
3357 // program allows the page change
3360 evt
.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
);
3361 (void)GetEventHandler()->ProcessEvent(evt
);
3367 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
3369 m_tabs
.SetActivePage(wnd
);
3371 ctrl
->SetActivePage(ctrl_idx
);
3375 ctrl
->MakeTabVisible(ctrl_idx
, ctrl
);
3378 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
3379 size_t i
, pane_count
= all_panes
.GetCount();
3380 for (i
= 0; i
< pane_count
; ++i
)
3382 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
3383 if (pane
.name
== wxT("dummy"))
3385 wxAuiTabCtrl
* tabctrl
= ((wxTabFrame
*)pane
.window
)->m_tabs
;
3386 if (tabctrl
!= ctrl
)
3387 tabctrl
->SetSelectedFont(m_normalFont
);
3389 tabctrl
->SetSelectedFont(m_selectedFont
);
3393 // Set the focus to the page if we're not currently focused on the tab.
3394 // This is Firefox-like behaviour.
3395 if (wnd
->IsShownOnScreen() && FindFocus() != ctrl
)