1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/aui/auibook.cpp
3 // Purpose: wxaui: wx advanced user interface - notebook
4 // Author: Benjamin I. Williams
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"
30 #include "wx/aui/tabmdi.h"
31 #include "wx/dcbuffer.h"
33 #include "wx/arrimpl.cpp"
34 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray
)
35 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray
)
37 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
)
38 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
)
39 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
)
40 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
)
41 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
)
42 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
)
46 IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent
, wxEvent
)
52 // This functions are here for this proof of concept
53 // and will be factored out later. See dockart.cpp
54 static wxColor
StepColour(const wxColor
& c
, int percent
)
56 int r
= c
.Red(), g
= c
.Green(), b
= c
.Blue();
57 return wxColour((unsigned char)wxMin((r
*percent
)/100,255),
58 (unsigned char)wxMin((g
*percent
)/100,255),
59 (unsigned char)wxMin((b
*percent
)/100,255));
62 // This functions are here for this proof of concept
63 // and will be factored out later. See dockart.cpp
64 static wxBitmap
BitmapFromBits(const unsigned char bits
[], int w
, int h
,
65 const wxColour
& color
)
67 wxImage img
= wxBitmap((const char*)bits
, w
, h
).ConvertToImage();
68 img
.Replace(0,0,0,123,123,123);
69 img
.Replace(255,255,255,color
.Red(),color
.Green(),color
.Blue());
70 img
.SetMaskColour(123,123,123);
74 static void DrawButtonS(wxDC
& dc
,
77 const wxColour
& bkcolour
,
82 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
88 if (button_state
== wxAUI_BUTTON_STATE_HOVER
||
89 button_state
== wxAUI_BUTTON_STATE_PRESSED
)
91 dc
.SetBrush(wxBrush(StepColour(bkcolour
, 120)));
92 dc
.SetPen(wxPen(StepColour(bkcolour
, 70)));
94 // draw the background behind the button
95 dc
.DrawRectangle(rect
.x
, rect
.y
, 15, 15);
98 // draw the button itself
99 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
106 // -- wxDefaultTabArt class implementation --
108 wxDefaultTabArt::wxDefaultTabArt()
110 m_normal_font
= *wxNORMAL_FONT
;
111 m_selected_font
= *wxNORMAL_FONT
;
112 m_selected_font
.SetWeight(wxBOLD
);
113 m_measuring_font
= m_selected_font
;
115 wxColour base_colour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
117 wxColour background_colour
= StepColour(base_colour
, 95);
118 wxColour normaltab_colour
= base_colour
;
119 wxColour selectedtab_colour
= *wxWHITE
;
121 m_bkbrush
= wxBrush(background_colour
);
122 m_normal_bkbrush
= wxBrush(normaltab_colour
);
123 m_normal_bkpen
= wxPen(normaltab_colour
);
124 m_selected_bkbrush
= wxBrush(selectedtab_colour
);
125 m_selected_bkpen
= wxPen(selectedtab_colour
);
128 #if defined( __WXMAC__ )
129 static unsigned char close_bits
[]={
130 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
131 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
132 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
133 #elif defined( __WXGTK__)
134 static unsigned char close_bits
[]={
135 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
136 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
137 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
139 static unsigned char close_bits
[]={
140 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xfb,0xcf,0xf9,
141 0x9f,0xfc,0x3f,0xfe,0x3f,0xfe,0x9f,0xfc,0xcf,0xf9,0xef,0xfb,
142 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
145 static unsigned char left_bits
[] = {
146 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
147 0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
148 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
150 static unsigned char right_bits
[] = {
151 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
152 0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
155 m_active_close_bmp
= BitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
156 m_disabled_close_bmp
= BitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
158 m_active_left_bmp
= BitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
159 m_disabled_left_bmp
= BitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
161 m_active_right_bmp
= BitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
162 m_disabled_right_bmp
= BitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
165 wxDefaultTabArt::~wxDefaultTabArt()
169 void wxDefaultTabArt::DrawBackground(wxDC
* dc
,
173 dc
->SetBrush(m_bkbrush
);
174 dc
->SetPen(*wxTRANSPARENT_PEN
);
175 dc
->DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2);
178 dc
->SetPen(*wxGREY_PEN
);
179 dc
->DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1);
183 // DrawTab() draws an individual tab.
186 // in_rect - rectangle the tab should be confined to
187 // caption - tab's caption
188 // active - whether or not the tab is active
189 // out_rect - actual output rectangle
190 // x_extent - the advance x; where the next tab should start
192 void wxDefaultTabArt::DrawTab(wxDC
* dc
,
193 const wxRect
& in_rect
,
194 const wxString
& caption_text
,
199 wxCoord normal_textx
, normal_texty
;
200 wxCoord selected_textx
, selected_texty
;
201 wxCoord measured_textx
, measured_texty
;
202 wxCoord textx
, texty
;
205 // if the caption is empty, measure some temporary text
206 wxString caption
= caption_text
;
207 if (caption_text
.empty())
211 dc
->SetFont(m_measuring_font
);
212 dc
->GetTextExtent(caption
, &measured_textx
, &measured_texty
);
214 dc
->SetFont(m_selected_font
);
215 dc
->GetTextExtent(caption
, &selected_textx
, &selected_texty
);
217 dc
->SetFont(m_normal_font
);
218 dc
->GetTextExtent(caption
, &normal_textx
, &normal_texty
);
220 caption
= caption_text
;
222 wxCoord tab_height
= measured_texty
+ 4;
223 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
224 wxCoord tab_x
= in_rect
.x
;
225 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
228 // select pen, brush and font for the tab to be drawn
232 dc
->SetPen(m_selected_bkpen
);
233 dc
->SetBrush(m_selected_bkbrush
);
234 dc
->SetFont(m_selected_font
);
235 textx
= selected_textx
;
236 texty
= selected_texty
;
240 dc
->SetPen(m_normal_bkpen
);
241 dc
->SetBrush(m_normal_bkbrush
);
242 dc
->SetFont(m_normal_font
);
243 textx
= normal_textx
;
244 texty
= normal_texty
;
252 points
[0].y
= tab_y
+ tab_height
- 1;
253 points
[1].x
= tab_x
+ tab_height
- 3;
254 points
[1].y
= tab_y
+ 2;
255 points
[2].x
= tab_x
+ tab_height
+ 3;
257 points
[3].x
= tab_x
+ tab_width
- 2;
259 points
[4].x
= tab_x
+ tab_width
;
260 points
[4].y
= tab_y
+ 2;
261 points
[5].x
= tab_x
+ tab_width
;
262 points
[5].y
= tab_y
+ tab_height
- 1;
263 points
[6] = points
[0];
266 dc
->DrawPolygon(6, points
);
268 dc
->SetPen(*wxGREY_PEN
);
270 //dc->DrawLines(active ? 6 : 7, points);
271 dc
->DrawLines(7, points
);
275 dc
->DrawText(caption
,
276 tab_x
+ (tab_height
/3) + (tab_width
/2) - (textx
/2),
277 tab_y
+ tab_height
- texty
- 2);
279 *out_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
280 *x_extent
= tab_width
- (tab_height
/2) - 1;
284 wxSize
wxDefaultTabArt::GetTabSize(wxDC
* dc
,
285 const wxString
& caption
,
286 bool WXUNUSED(active
),
289 wxCoord measured_textx
, measured_texty
;
291 dc
->SetFont(m_measuring_font
);
292 dc
->GetTextExtent(caption
, &measured_textx
, &measured_texty
);
294 wxCoord tab_height
= measured_texty
+ 4;
295 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
297 *x_extent
= tab_width
- (tab_height
/2) - 1;
299 return wxSize(tab_width
, tab_height
);
303 void wxDefaultTabArt::DrawButton(
305 const wxRect
& in_rect
,
309 const wxBitmap
& bitmap_override
,
315 if (bitmap_override
.IsOk())
317 bmp
= bitmap_override
;
323 case wxAUI_BUTTON_CLOSE
:
324 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
325 bmp
= m_disabled_close_bmp
;
327 bmp
= m_active_close_bmp
;
329 case wxAUI_BUTTON_LEFT
:
330 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
331 bmp
= m_disabled_left_bmp
;
333 bmp
= m_active_left_bmp
;
335 case wxAUI_BUTTON_RIGHT
:
336 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
337 bmp
= m_disabled_right_bmp
;
339 bmp
= m_active_right_bmp
;
349 if (orientation
== wxLEFT
)
351 rect
.SetWidth(bmp
.GetWidth());
352 rect
.SetHeight(bmp
.GetHeight());
356 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(), in_rect
.y
,
357 bmp
.GetWidth(), bmp
.GetHeight());
361 DrawButtonS(*dc
, rect
, bmp
, *wxWHITE
, button_state
);
370 void wxDefaultTabArt::SetNormalFont(const wxFont
& font
)
372 m_normal_font
= font
;
375 void wxDefaultTabArt::SetSelectedFont(const wxFont
& font
)
377 m_selected_font
= font
;
380 void wxDefaultTabArt::SetMeasuringFont(const wxFont
& font
)
382 m_measuring_font
= font
;
390 // -- wxAuiTabContainer class implementation --
393 // wxAuiTabContainer is a class which contains information about each
394 // tab. It also can render an entire tab control to a specified DC.
395 // It's not a window class itself, because this code will be used by
396 // the wxFrameMananger, where it is disadvantageous to have separate
397 // windows for each tab control in the case of "docked tabs"
399 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window
400 // which can be used as a tab control in the normal sense.
403 wxAuiTabContainer::wxAuiTabContainer()
406 m_art
= new wxDefaultTabArt
;
408 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
409 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
410 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
413 wxAuiTabContainer::~wxAuiTabContainer()
418 void wxAuiTabContainer::SetArtProvider(wxTabArt
* art
)
424 wxTabArt
* wxAuiTabContainer::GetArtProvider()
429 void wxAuiTabContainer::SetNormalFont(const wxFont
& font
)
431 m_art
->SetNormalFont(font
);
434 void wxAuiTabContainer::SetSelectedFont(const wxFont
& font
)
436 m_art
->SetSelectedFont(font
);
439 void wxAuiTabContainer::SetMeasuringFont(const wxFont
& font
)
441 m_art
->SetMeasuringFont(font
);
444 void wxAuiTabContainer::SetRect(const wxRect
& rect
)
449 bool wxAuiTabContainer::AddPage(wxWindow
* page
,
450 const wxAuiNotebookPage
& info
)
452 wxAuiNotebookPage page_info
;
454 page_info
.window
= page
;
456 m_pages
.Add(page_info
);
461 bool wxAuiTabContainer::InsertPage(wxWindow
* page
,
462 const wxAuiNotebookPage
& info
,
465 wxAuiNotebookPage page_info
;
467 page_info
.window
= page
;
469 if (idx
>= m_pages
.GetCount())
470 m_pages
.Add(page_info
);
472 m_pages
.Insert(page_info
, idx
);
477 bool wxAuiTabContainer::RemovePage(wxWindow
* wnd
)
479 size_t i
, page_count
= m_pages
.GetCount();
480 for (i
= 0; i
< page_count
; ++i
)
482 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
483 if (page
.window
== wnd
)
493 bool wxAuiTabContainer::SetActivePage(wxWindow
* wnd
)
497 size_t i
, page_count
= m_pages
.GetCount();
498 for (i
= 0; i
< page_count
; ++i
)
500 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
501 if (page
.window
== wnd
)
515 void wxAuiTabContainer::SetNoneActive()
517 size_t i
, page_count
= m_pages
.GetCount();
518 for (i
= 0; i
< page_count
; ++i
)
520 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
525 bool wxAuiTabContainer::SetActivePage(size_t page
)
527 if (page
>= m_pages
.GetCount())
530 return SetActivePage(m_pages
.Item(page
).window
);
533 int wxAuiTabContainer::GetActivePage() const
535 size_t i
, page_count
= m_pages
.GetCount();
536 for (i
= 0; i
< page_count
; ++i
)
538 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
546 wxWindow
* wxAuiTabContainer::GetWindowFromIdx(size_t idx
) const
548 if (idx
>= m_pages
.GetCount())
551 return m_pages
[idx
].window
;
554 int wxAuiTabContainer::GetIdxFromWindow(wxWindow
* wnd
) const
556 size_t i
, page_count
= m_pages
.GetCount();
557 for (i
= 0; i
< page_count
; ++i
)
559 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
560 if (page
.window
== wnd
)
566 wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
)
568 wxASSERT_MSG(idx
< m_pages
.GetCount(), wxT("Invalid Page index"));
573 wxAuiNotebookPageArray
& wxAuiTabContainer::GetPages()
578 size_t wxAuiTabContainer::GetPageCount() const
580 return m_pages
.GetCount();
583 void wxAuiTabContainer::AddButton(int id
,
585 const wxBitmap
& normal_bitmap
,
586 const wxBitmap
& disabled_bitmap
)
588 wxAuiTabContainerButton button
;
590 button
.bitmap
= normal_bitmap
;
591 button
.dis_bitmap
= disabled_bitmap
;
592 button
.location
= location
;
593 button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
595 m_buttons
.Add(button
);
598 size_t wxAuiTabContainer::GetTabOffset() const
603 void wxAuiTabContainer::SetTabOffset(size_t offset
)
605 m_tab_offset
= offset
;
608 // Render() renders the tab catalog to the specified DC
609 // It is a virtual function and can be overridden to
610 // provide custom drawing capabilities
611 void wxAuiTabContainer::Render(wxDC
* raw_dc
)
616 size_t page_count
= m_pages
.GetCount();
617 size_t button_count
= m_buttons
.GetCount();
619 // create off-screen bitmap
620 bmp
.Create(m_rect
.GetWidth(), m_rect
.GetHeight());
621 dc
.SelectObject(bmp
);
624 // find out if size of tabs is larger than can be
625 // afforded on screen
628 for (i
= 0; i
< page_count
; ++i
)
630 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
632 wxSize size
= m_art
->GetTabSize(&dc
, page
.caption
, page
.active
, &x_extent
);
633 if (i
+1 < page_count
)
634 total_width
+= x_extent
;
636 total_width
+= size
.x
;
639 if (total_width
> m_rect
.GetWidth() - 20 || m_tab_offset
!= 0)
641 // show left/right buttons
642 for (i
= 0; i
< button_count
; ++i
)
644 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
645 if (button
.id
== wxAUI_BUTTON_LEFT
||
646 button
.id
== wxAUI_BUTTON_RIGHT
)
648 button
.cur_state
&= ~wxAUI_BUTTON_STATE_HIDDEN
;
654 // hide left/right buttons
655 for (i
= 0; i
< button_count
; ++i
)
657 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
658 if (button
.id
== wxAUI_BUTTON_LEFT
||
659 button
.id
== wxAUI_BUTTON_RIGHT
)
661 button
.cur_state
|= wxAUI_BUTTON_STATE_HIDDEN
;
669 m_art
->DrawBackground(&dc
, m_rect
);
672 int left_buttons_width
= 0;
673 int right_buttons_width
= 0;
677 // draw the buttons on the right side
678 offset
= m_rect
.x
+ m_rect
.width
;
679 for (i
= 0; i
< button_count
; ++i
)
681 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
683 if (button
.location
!= wxRIGHT
)
685 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
688 wxRect button_rect
= m_rect
;
690 button_rect
.SetWidth(offset
);
692 m_art
->DrawButton(&dc
,
700 offset
-= button
.rect
.GetWidth();
701 right_buttons_width
+= button
.rect
.GetWidth();
708 // draw the buttons on the left side
710 for (i
= 0; i
< button_count
; ++i
)
712 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
714 if (button
.location
!= wxLEFT
)
716 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
719 wxRect
button_rect(offset
, 1, 1000, m_rect
.height
);
721 m_art
->DrawButton(&dc
,
729 offset
+= button
.rect
.GetWidth();
730 left_buttons_width
+= button
.rect
.GetWidth();
733 offset
= left_buttons_width
;
736 dc
.SetClippingRegion(left_buttons_width
, 0,
737 m_rect
.GetWidth() - right_buttons_width
- left_buttons_width
- 2,
743 int active_offset
= 0;
746 wxRect rect
= m_rect
;
749 rect
.height
= m_rect
.height
;
751 for (i
= m_tab_offset
; i
< page_count
; ++i
)
753 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
767 active_offset
= offset
;
773 // draw the active tab again so it stands in the foreground
774 if (active
>= m_tab_offset
&& active
< m_pages
.GetCount())
776 wxAuiNotebookPage
& page
= m_pages
.Item(active
);
778 rect
.x
= active_offset
;
787 dc
.DestroyClippingRegion();
789 raw_dc
->Blit(m_rect
.x
, m_rect
.y
,
790 m_rect
.GetWidth(), m_rect
.GetHeight(),
795 // TabHitTest() tests if a tab was hit, passing the window pointer
796 // back if that condition was fulfilled. The function returns
797 // true if a tab was hit, otherwise false
798 bool wxAuiTabContainer::TabHitTest(int x
, int y
, wxWindow
** hit
) const
800 if (!m_rect
.Contains(x
,y
))
803 if (ButtonHitTest(x
, y
, NULL
))
806 size_t i
, page_count
= m_pages
.GetCount();
808 for (i
= m_tab_offset
; i
< page_count
; ++i
)
810 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
811 if (page
.rect
.Contains(x
,y
))
822 // ButtonHitTest() tests if a button was hit. The function returns
823 // true if a button was hit, otherwise false
824 bool wxAuiTabContainer::ButtonHitTest(int x
, int y
,
825 wxAuiTabContainerButton
** hit
) const
827 if (!m_rect
.Contains(x
,y
))
830 size_t i
, button_count
= m_buttons
.GetCount();
832 for (i
= 0; i
< button_count
; ++i
)
834 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
835 if (button
.rect
.Contains(x
,y
))
848 // the utility function ShowWnd() is the same as show,
849 // except it handles wxTabMDIChildFrame windows as well,
850 // as the Show() method on this class is "unplugged"
851 static void ShowWnd(wxWindow
* wnd
, bool show
)
853 if (wnd
->IsKindOf(CLASSINFO(wxTabMDIChildFrame
)))
855 wxTabMDIChildFrame
* cf
= (wxTabMDIChildFrame
*)wnd
;
865 // DoShowHide() this function shows the active window, then
866 // hides all of the other windows (in that order)
867 void wxAuiTabContainer::DoShowHide()
869 wxAuiNotebookPageArray
& pages
= GetPages();
870 size_t i
, page_count
= pages
.GetCount();
872 // show new active page first
873 for (i
= 0; i
< page_count
; ++i
)
875 wxAuiNotebookPage
& page
= pages
.Item(i
);
878 ShowWnd(page
.window
, true);
883 // hide all other pages
884 for (i
= 0; i
< page_count
; ++i
)
886 wxAuiNotebookPage
& page
= pages
.Item(i
);
887 ShowWnd(page
.window
, page
.active
);
896 // -- wxAuiTabCtrl class implementation --
900 BEGIN_EVENT_TABLE(wxAuiTabCtrl
, wxControl
)
901 EVT_PAINT(wxAuiTabCtrl::OnPaint
)
902 EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground
)
903 EVT_SIZE(wxAuiTabCtrl::OnSize
)
904 EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown
)
905 EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp
)
906 EVT_MOTION(wxAuiTabCtrl::OnMotion
)
907 EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow
)
908 EVT_AUINOTEBOOK_BUTTON(-1, wxAuiTabCtrl::OnButton
)
912 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow
* parent
,
916 long style
) : wxControl(parent
, id
, pos
, size
, style
)
918 m_click_pt
= wxDefaultPosition
;
919 m_is_dragging
= false;
920 m_hover_button
= NULL
;
924 void wxAuiTabCtrl::OnPaint(wxPaintEvent
&)
928 dc
.SetFont(GetFont());
930 if (GetPageCount() > 0)
934 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent
& WXUNUSED(evt
))
938 void wxAuiTabCtrl::OnSize(wxSizeEvent
& evt
)
940 wxSize s
= evt
.GetSize();
941 wxRect
r(0, 0, s
.GetWidth(), s
.GetHeight());
945 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent
& evt
)
948 m_click_pt
= wxDefaultPosition
;
949 m_is_dragging
= false;
953 if (TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
955 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
956 e
.SetSelection(GetIdxFromWindow(wnd
));
957 e
.SetOldSelection(GetActivePage());
958 e
.SetEventObject(this);
959 GetEventHandler()->ProcessEvent(e
);
961 m_click_pt
.x
= evt
.m_x
;
962 m_click_pt
.y
= evt
.m_y
;
963 m_click_tab
= e
.GetSelection();
968 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_PRESSED
;
974 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent
&)
976 if (GetCapture() == this)
981 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, m_windowId
);
982 evt
.SetSelection(m_click_tab
);
983 evt
.SetOldSelection(m_click_tab
);
984 evt
.SetEventObject(this);
985 GetEventHandler()->ProcessEvent(evt
);
991 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_HOVER
;
995 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, m_windowId
);
996 evt
.SetInt(m_hover_button
->id
);
997 evt
.SetEventObject(this);
998 GetEventHandler()->ProcessEvent(evt
);
1001 m_click_pt
= wxDefaultPosition
;
1002 m_is_dragging
= false;
1006 void wxAuiTabCtrl::OnMotion(wxMouseEvent
& evt
)
1008 wxPoint pos
= evt
.GetPosition();
1010 // check if the mouse is hovering above a button
1011 wxAuiTabContainerButton
* button
;
1012 if (ButtonHitTest(pos
.x
, pos
.y
, &button
))
1014 if (m_hover_button
&& button
!= m_hover_button
)
1016 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1017 m_hover_button
= NULL
;
1022 if (button
->cur_state
!= wxAUI_BUTTON_STATE_HOVER
)
1024 button
->cur_state
= wxAUI_BUTTON_STATE_HOVER
;
1027 m_hover_button
= button
;
1035 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1036 m_hover_button
= NULL
;
1043 if (!evt
.LeftIsDown() || m_click_pt
== wxDefaultPosition
)
1048 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, m_windowId
);
1049 evt
.SetSelection(m_click_tab
);
1050 evt
.SetOldSelection(m_click_tab
);
1051 evt
.SetEventObject(this);
1052 GetEventHandler()->ProcessEvent(evt
);
1057 int drag_x_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_X
);
1058 int drag_y_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_Y
);
1060 if (abs(pos
.x
- m_click_pt
.x
) > drag_x_threshold
||
1061 abs(pos
.y
- m_click_pt
.y
) > drag_y_threshold
)
1063 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, m_windowId
);
1064 evt
.SetSelection(m_click_tab
);
1065 evt
.SetOldSelection(m_click_tab
);
1066 evt
.SetEventObject(this);
1067 GetEventHandler()->ProcessEvent(evt
);
1069 m_is_dragging
= true;
1073 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
))
1077 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1078 m_hover_button
= NULL
;
1084 void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent
& event
)
1086 int button
= event
.GetInt();
1088 if (button
== wxAUI_BUTTON_LEFT
|| button
== wxAUI_BUTTON_RIGHT
)
1090 if (button
== wxAUI_BUTTON_LEFT
)
1092 if (GetTabOffset() > 0)
1094 SetTabOffset(GetTabOffset()-1);
1101 SetTabOffset(GetTabOffset()+1);
1112 // wxTabFrame is an interesting case. It's important that all child pages
1113 // of the multi-notebook control are all actually children of that control
1114 // (and not grandchildren). wxTabFrame facilitates this. There is one
1115 // instance of wxTabFrame for each tab control inside the multi-notebook.
1116 // It's important to know that wxTabFrame is not a real window, but it merely
1117 // used to capture the dimensions/positioning of the internal tab control and
1118 // it's managed page windows
1120 class wxTabFrame
: public wxWindow
1127 m_rect
= wxRect(0,0,200,200);
1128 m_tab_ctrl_height
= 20;
1131 void SetTabCtrlHeight(int h
)
1133 m_tab_ctrl_height
= h
;
1136 void DoSetSize(int x
, int y
,
1137 int width
, int height
,
1138 int WXUNUSED(sizeFlags
= wxSIZE_AUTO
))
1140 m_rect
= wxRect(x
, y
, width
, height
);
1144 void DoGetClientSize(int* x
, int* y
) const
1150 bool Show( bool WXUNUSED(show
= true) ) { return false; }
1157 int tab_height
= wxMin(m_rect
.height
, m_tab_ctrl_height
);
1158 m_tab_rect
= wxRect(m_rect
.x
, m_rect
.y
, m_rect
.width
, tab_height
);
1159 m_tabs
->SetSize(m_rect
.x
, m_rect
.y
, m_rect
.width
, tab_height
);
1160 m_tabs
->SetRect(wxRect(0, 0, m_rect
.width
, tab_height
));
1164 wxAuiNotebookPageArray
& pages
= m_tabs
->GetPages();
1165 size_t i
, page_count
= pages
.GetCount();
1167 for (i
= 0; i
< page_count
; ++i
)
1169 wxAuiNotebookPage
& page
= pages
.Item(i
);
1170 page
.window
->SetSize(m_rect
.x
, m_rect
.y
+tab_height
, m_rect
.width
, m_rect
.height
-tab_height
);
1172 if (page
.window
->IsKindOf(CLASSINFO(wxTabMDIChildFrame
)))
1174 wxTabMDIChildFrame
* wnd
= (wxTabMDIChildFrame
*)page
.window
;
1175 wnd
->ApplyMDIChildFrameRect();
1180 void DoGetSize(int* x
, int* y
) const
1183 *x
= m_rect
.GetWidth();
1185 *y
= m_rect
.GetHeight();
1197 wxAuiTabCtrl
* m_tabs
;
1198 int m_tab_ctrl_height
;
1205 // -- wxAuiMultiNotebook class implementation --
1207 BEGIN_EVENT_TABLE(wxAuiMultiNotebook
, wxControl
)
1208 //EVT_ERASE_BACKGROUND(wxAuiMultiNotebook::OnEraseBackground)
1209 //EVT_SIZE(wxAuiMultiNotebook::OnSize)
1210 //EVT_LEFT_DOWN(wxAuiMultiNotebook::OnLeftDown)
1211 EVT_CHILD_FOCUS(wxAuiMultiNotebook::OnChildFocus
)
1212 EVT_COMMAND_RANGE(10000, 10100,
1213 wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
,
1214 wxAuiMultiNotebook::OnTabClicked
)
1215 EVT_COMMAND_RANGE(10000, 10100,
1216 wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
,
1217 wxAuiMultiNotebook::OnTabBeginDrag
)
1218 EVT_COMMAND_RANGE(10000, 10100,
1219 wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
,
1220 wxAuiMultiNotebook::OnTabEndDrag
)
1221 EVT_COMMAND_RANGE(10000, 10100,
1222 wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
,
1223 wxAuiMultiNotebook::OnTabDragMotion
)
1224 EVT_COMMAND_RANGE(10000, 10100,
1225 wxEVT_COMMAND_AUINOTEBOOK_BUTTON
,
1226 wxAuiMultiNotebook::OnTabButton
)
1229 wxAuiMultiNotebook::wxAuiMultiNotebook()
1232 m_tab_id_counter
= 10000;
1234 m_tab_ctrl_height
= 20;
1237 wxAuiMultiNotebook::wxAuiMultiNotebook(wxWindow
*parent
,
1241 long style
) : wxControl(parent
, id
, pos
, size
, style
)
1246 bool wxAuiMultiNotebook::Create(wxWindow
* parent
,
1252 if (!wxControl::Create(parent
, id
, pos
, size
, style
))
1260 // InitNotebook() contains common initialization
1261 // code called by all constructors
1262 void wxAuiMultiNotebook::InitNotebook()
1265 m_tab_id_counter
= 10000;
1267 m_tab_ctrl_height
= 20;
1269 m_normal_font
= *wxNORMAL_FONT
;
1270 m_selected_font
= *wxNORMAL_FONT
;
1271 m_selected_font
.SetWeight(wxBOLD
);
1273 // choose a default for the tab height
1274 wxClientDC
dc(this);
1276 dc
.SetFont(m_selected_font
);
1277 dc
.GetTextExtent(wxT("ABCDEFGHhijklm"), &tx
, &ty
);
1278 m_tab_ctrl_height
= (ty
*150)/100;
1280 m_dummy_wnd
= new wxWindow(this, wxID_ANY
, wxPoint(0,0), wxSize(0,0));
1281 m_dummy_wnd
->SetSize(200, 200);
1282 m_dummy_wnd
->Show(false);
1284 m_mgr
.SetManagedWindow(this);
1286 m_mgr
.AddPane(m_dummy_wnd
,
1287 wxPaneInfo().Name(wxT("dummy")).Bottom().Show(false));
1292 wxAuiMultiNotebook::~wxAuiMultiNotebook()
1297 void wxAuiMultiNotebook::SetArtProvider(wxTabArt
* art
)
1299 m_tabs
.SetArtProvider(art
);
1302 wxTabArt
* wxAuiMultiNotebook::GetArtProvider()
1304 return m_tabs
.GetArtProvider();
1307 bool wxAuiMultiNotebook::AddPage(wxWindow
* page
,
1308 const wxString
& caption
,
1310 const wxBitmap
& bitmap
)
1312 return InsertPage(GetPageCount(), page
, caption
, select
, bitmap
);
1315 bool wxAuiMultiNotebook::InsertPage(size_t page_idx
,
1317 const wxString
& caption
,
1319 const wxBitmap
& bitmap
)
1321 wxAuiNotebookPage info
;
1323 info
.caption
= caption
;
1324 info
.bitmap
= bitmap
;
1325 info
.active
= false;
1327 // if there are currently no tabs, the first added
1328 // tab must be active
1329 if (m_tabs
.GetPageCount() == 0)
1332 m_tabs
.InsertPage(page
, info
, page_idx
);
1334 wxAuiTabCtrl
* active_tabctrl
= GetActiveTabCtrl();
1335 if (page_idx
>= active_tabctrl
->GetPageCount())
1336 active_tabctrl
->AddPage(page
, info
);
1338 active_tabctrl
->InsertPage(page
, info
, page_idx
);
1341 active_tabctrl
->DoShowHide();
1345 int idx
= m_tabs
.GetIdxFromWindow(page
);
1346 wxASSERT_MSG(idx
!= -1, wxT("Invalid Page index returned on wxAuiMultiNotebook::InsertPage()"));
1355 // DeletePage() removes a tab from the multi-notebook,
1356 // and destroys the window as well
1357 bool wxAuiMultiNotebook::DeletePage(size_t page_idx
)
1359 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
1360 wxWindow
* new_active
= NULL
;
1362 // find out which onscreen tab ctrl owns this tab
1365 if (!FindTab(wnd
, &ctrl
, &ctrl_idx
))
1368 // find a new page and set it as active
1369 int new_idx
= ctrl_idx
+1;
1370 if (new_idx
>= (int)ctrl
->GetPageCount())
1371 new_idx
= ctrl_idx
-1;
1373 if (new_idx
>= 0 && new_idx
< (int)ctrl
->GetPageCount())
1375 new_active
= ctrl
->GetWindowFromIdx(new_idx
);
1379 // set the active page to the first page that
1380 // isn't the one being deleted
1381 size_t i
, page_count
= m_tabs
.GetPageCount();
1382 for (i
= 0; i
< page_count
; ++i
)
1384 wxWindow
* w
= m_tabs
.GetWindowFromIdx(i
);
1387 new_active
= m_tabs
.GetWindowFromIdx(i
);
1393 // remove the tab from main catalog
1394 if (!m_tabs
.RemovePage(wnd
))
1397 // remove the tab from the onscreen tab ctrl
1398 ctrl
->RemovePage(wnd
);
1400 // actually destroy the window now
1401 if (wnd
->IsKindOf(CLASSINFO(wxTabMDIChildFrame
)))
1403 // delete the child frame with pending delete, as is
1404 // customary with frame windows
1405 if (!wxPendingDelete
.Member(wnd
))
1406 wxPendingDelete
.Append(wnd
);
1413 RemoveEmptyTabFrames();
1415 // set new active pane
1419 SetSelection(m_tabs
.GetIdxFromWindow(new_active
));
1427 // RemovePage() removes a tab from the multi-notebook,
1428 // but does not destroy the window
1429 bool wxAuiMultiNotebook::RemovePage(size_t page_idx
)
1431 // remove the tab from our own catalog
1432 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
1433 if (!m_tabs
.RemovePage(wnd
))
1436 // remove the tab from the onscreen tab ctrl
1439 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
1441 ctrl
->RemovePage(wnd
);
1448 // SetPageText() changes the tab caption of the specified page
1449 bool wxAuiMultiNotebook::SetPageText(size_t page_idx
, const wxString
& text
)
1451 if (page_idx
>= m_tabs
.GetPageCount())
1454 // update our own tab catalog
1455 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
1456 page_info
.caption
= text
;
1458 // update what's on screen
1461 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
1463 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
1464 info
.caption
= text
;
1472 // GetSelection() returns the index of the currently active page
1473 int wxAuiMultiNotebook::GetSelection() const
1478 // SetSelection() sets the currently active page
1479 size_t wxAuiMultiNotebook::SetSelection(size_t new_page
)
1481 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(new_page
);
1485 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
1486 evt
.SetSelection(new_page
);
1487 evt
.SetOldSelection(m_curpage
);
1488 evt
.SetEventObject(this);
1489 if (!GetEventHandler()->ProcessEvent(evt
) || evt
.IsAllowed())
1491 // program allows the page change
1492 evt
.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
);
1493 (void)GetEventHandler()->ProcessEvent(evt
);
1499 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
1501 m_tabs
.SetActivePage(wnd
);
1503 ctrl
->SetActivePage(ctrl_idx
);
1507 int old_curpage
= m_curpage
;
1508 m_curpage
= new_page
;
1512 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1513 size_t i
, pane_count
= all_panes
.GetCount();
1514 for (i
= 0; i
< pane_count
; ++i
)
1516 wxPaneInfo
& pane
= all_panes
.Item(i
);
1517 if (pane
.name
== wxT("dummy"))
1519 wxAuiTabCtrl
* tabctrl
= ((wxTabFrame
*)pane
.window
)->m_tabs
;
1520 if (tabctrl
!= ctrl
)
1521 tabctrl
->SetSelectedFont(m_normal_font
);
1523 tabctrl
->SetSelectedFont(m_selected_font
);
1536 // GetPageCount() returns the total number of
1537 // pages managed by the multi-notebook
1538 size_t wxAuiMultiNotebook::GetPageCount() const
1540 return m_tabs
.GetPageCount();
1543 // GetPage() returns the wxWindow pointer of the
1545 wxWindow
* wxAuiMultiNotebook::GetPage(size_t page_idx
) const
1547 wxASSERT(page_idx
< m_tabs
.GetPageCount());
1549 return m_tabs
.GetWindowFromIdx(page_idx
);
1552 // DoSizing() performs all sizing operations in each tab control
1553 void wxAuiMultiNotebook::DoSizing()
1555 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1556 size_t i
, pane_count
= all_panes
.GetCount();
1557 for (i
= 0; i
< pane_count
; ++i
)
1559 if (all_panes
.Item(i
).name
== wxT("dummy"))
1562 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1563 tabframe
->DoSizing();
1567 // GetActiveTabCtrl() returns the active tab control. It is
1568 // called to determine which control gets new windows being added
1569 wxAuiTabCtrl
* wxAuiMultiNotebook::GetActiveTabCtrl()
1571 if (m_curpage
>= 0 && m_curpage
< (int)m_tabs
.GetPageCount())
1576 // find the tab ctrl with the current page
1577 if (FindTab(m_tabs
.GetPage(m_curpage
).window
,
1584 // no current page, just find the first tab ctrl
1585 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1586 size_t i
, pane_count
= all_panes
.GetCount();
1587 for (i
= 0; i
< pane_count
; ++i
)
1589 if (all_panes
.Item(i
).name
== wxT("dummy"))
1592 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1593 return tabframe
->m_tabs
;
1596 // If there is no tabframe at all, create one
1597 wxTabFrame
* tabframe
= new wxTabFrame
;
1598 tabframe
->SetTabCtrlHeight(m_tab_ctrl_height
);
1599 tabframe
->m_tabs
= new wxAuiTabCtrl(this,
1604 m_mgr
.AddPane(tabframe
,
1605 wxPaneInfo().Center().CaptionVisible(false));
1609 return tabframe
->m_tabs
;
1612 // FindTab() finds the tab control that currently contains the window as well
1613 // as the index of the window in the tab control. It returns true if the
1614 // window was found, otherwise false.
1615 bool wxAuiMultiNotebook::FindTab(wxWindow
* page
, wxAuiTabCtrl
** ctrl
, int* idx
)
1617 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1618 size_t i
, pane_count
= all_panes
.GetCount();
1619 for (i
= 0; i
< pane_count
; ++i
)
1621 if (all_panes
.Item(i
).name
== wxT("dummy"))
1624 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1626 int page_idx
= tabframe
->m_tabs
->GetIdxFromWindow(page
);
1629 *ctrl
= tabframe
->m_tabs
;
1639 void wxAuiMultiNotebook::OnEraseBackground(wxEraseEvent
&)
1643 void wxAuiMultiNotebook::OnSize(wxSizeEvent
&)
1647 void wxAuiMultiNotebook::OnTabClicked(wxCommandEvent
& command_evt
)
1649 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
1651 wxAuiTabCtrl
* ctrl
= (wxAuiTabCtrl
*)evt
.GetEventObject();
1652 wxASSERT(ctrl
!= NULL
);
1654 wxWindow
* wnd
= ctrl
->GetWindowFromIdx(evt
.GetSelection());
1655 wxASSERT(wnd
!= NULL
);
1657 int idx
= m_tabs
.GetIdxFromWindow(wnd
);
1658 wxASSERT(idx
!= -1);
1663 void wxAuiMultiNotebook::OnTabBeginDrag(wxCommandEvent
&)
1667 void wxAuiMultiNotebook::OnTabDragMotion(wxCommandEvent
& evt
)
1669 wxPoint screen_pt
= ::wxGetMousePosition();
1670 wxPoint client_pt
= ScreenToClient(screen_pt
);
1673 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
1675 wxAuiTabCtrl
* tab_ctrl
= GetTabCtrlFromPoint(client_pt
);
1676 if (tab_ctrl
== src_tabs
)
1678 // inner-tabctrl dragging is not yet implemented
1685 wxRect hint_rect
= tab_ctrl
->GetRect();
1686 ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
1687 m_mgr
.ShowHint(hint_rect
);
1691 m_mgr
.DrawHintRect(m_dummy_wnd
, client_pt
, zero
);
1697 void wxAuiMultiNotebook::OnTabEndDrag(wxCommandEvent
& command_evt
)
1699 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
1704 // get the mouse position, which will be used to determine the drop point
1705 wxPoint mouse_screen_pt
= ::wxGetMousePosition();
1706 wxPoint mouse_client_pt
= ScreenToClient(mouse_screen_pt
);
1709 // the src tab control is the control that fired this event
1710 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
1711 wxAuiTabCtrl
* dest_tabs
= NULL
;
1714 // If the pointer is in an existing tab frame, do a tab insert
1715 wxWindow
* hit_wnd
= ::wxFindWindowAtPoint(mouse_screen_pt
);
1716 wxTabFrame
* tab_frame
= (wxTabFrame
*)GetTabFrameFromTabCtrl(hit_wnd
);
1719 dest_tabs
= tab_frame
->m_tabs
;
1721 if (dest_tabs
== src_tabs
)
1726 // If there is no tabframe at all, create one
1727 wxTabFrame
* new_tabs
= new wxTabFrame
;
1728 new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
);
1729 new_tabs
->m_tabs
= new wxAuiTabCtrl(this,
1734 m_mgr
.AddPane(new_tabs
,
1735 wxPaneInfo().Bottom().CaptionVisible(false),
1738 dest_tabs
= new_tabs
->m_tabs
;
1743 // remove the page from the source tabs
1744 wxAuiNotebookPage page_info
= src_tabs
->GetPage(evt
.GetSelection());
1745 page_info
.active
= false;
1746 src_tabs
->RemovePage(page_info
.window
);
1747 if (src_tabs
->GetPageCount() > 0)
1749 src_tabs
->SetActivePage((size_t)0);
1750 src_tabs
->DoShowHide();
1751 src_tabs
->Refresh();
1756 // add the page to the destination tabs
1757 dest_tabs
->AddPage(page_info
.window
, page_info
);
1759 if (src_tabs
->GetPageCount() == 0)
1761 RemoveEmptyTabFrames();
1765 dest_tabs
->DoShowHide();
1766 dest_tabs
->Refresh();
1768 SetSelection(m_tabs
.GetIdxFromWindow(page_info
.window
));
1771 wxAuiTabCtrl
* wxAuiMultiNotebook::GetTabCtrlFromPoint(const wxPoint
& pt
)
1773 // if we've just removed the last tab from the source
1774 // tab set, the remove the tab control completely
1775 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1776 size_t i
, pane_count
= all_panes
.GetCount();
1777 for (i
= 0; i
< pane_count
; ++i
)
1779 if (all_panes
.Item(i
).name
== wxT("dummy"))
1782 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1783 if (tabframe
->m_tab_rect
.Contains(pt
))
1784 return tabframe
->m_tabs
;
1790 wxWindow
* wxAuiMultiNotebook::GetTabFrameFromTabCtrl(wxWindow
* tab_ctrl
)
1792 // if we've just removed the last tab from the source
1793 // tab set, the remove the tab control completely
1794 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1795 size_t i
, pane_count
= all_panes
.GetCount();
1796 for (i
= 0; i
< pane_count
; ++i
)
1798 if (all_panes
.Item(i
).name
== wxT("dummy"))
1801 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1802 if (tabframe
->m_tabs
== tab_ctrl
)
1811 void wxAuiMultiNotebook::RemoveEmptyTabFrames()
1813 // if we've just removed the last tab from the source
1814 // tab set, the remove the tab control completely
1815 wxPaneInfoArray all_panes
= m_mgr
.GetAllPanes();
1816 size_t i
, pane_count
= all_panes
.GetCount();
1817 for (i
= 0; i
< pane_count
; ++i
)
1819 if (all_panes
.Item(i
).name
== wxT("dummy"))
1822 wxTabFrame
* tab_frame
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1823 if (tab_frame
->m_tabs
->GetPageCount() == 0)
1825 m_mgr
.DetachPane(tab_frame
);
1827 // use pending delete because sometimes during
1828 // window closing, refreshs are pending
1829 if (!wxPendingDelete
.Member(tab_frame
->m_tabs
))
1830 wxPendingDelete
.Append(tab_frame
->m_tabs
);
1831 //tab_frame->m_tabs->Destroy();
1838 // check to see if there is still a center pane;
1839 // if there isn't, make a frame the center pane
1840 wxPaneInfoArray panes
= m_mgr
.GetAllPanes();
1841 pane_count
= panes
.GetCount();
1842 wxWindow
* first_good
= NULL
;
1843 bool center_found
= false;
1844 for (i
= 0; i
< pane_count
; ++i
)
1846 if (panes
.Item(i
).name
== wxT("dummy"))
1848 if (panes
.Item(i
).dock_direction
== wxAUI_DOCK_CENTRE
)
1849 center_found
= true;
1851 first_good
= panes
.Item(i
).window
;
1854 if (!center_found
&& first_good
)
1856 m_mgr
.GetPane(first_good
).Centre();
1862 void wxAuiMultiNotebook::OnChildFocus(wxChildFocusEvent
& evt
)
1864 int idx
= m_tabs
.GetIdxFromWindow(evt
.GetWindow());
1865 if (idx
!= -1 && idx
!= m_curpage
)
1872 void wxAuiMultiNotebook::OnTabButton(wxCommandEvent
& command_evt
)
1874 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
1875 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
1877 int button_id
= evt
.GetInt();
1879 if (button_id
== wxAUI_BUTTON_CLOSE
)
1881 int selection
= tabs
->GetActivePage();
1883 if (selection
!= -1)
1885 wxWindow
* close_wnd
= tabs
->GetWindowFromIdx(selection
);
1887 if (close_wnd
->IsKindOf(CLASSINFO(wxTabMDIChildFrame
)))
1893 int main_idx
= m_tabs
.GetIdxFromWindow(close_wnd
);
1894 DeletePage(main_idx
);