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 textx
, texty
;
203 // if the caption is empty, measure some temporary text
204 wxString caption
= caption_text
;
205 if (caption_text
.empty())
208 dc
->SetFont(m_selected_font
);
209 dc
->GetTextExtent(caption
, &selected_textx
, &selected_texty
);
211 dc
->SetFont(m_normal_font
);
212 dc
->GetTextExtent(caption
, &normal_textx
, &normal_texty
);
214 // figure out the size of the tab
215 wxSize tab_size
= GetTabSize(dc
, caption
, active
, x_extent
);
217 wxCoord tab_height
= tab_size
.y
;
218 wxCoord tab_width
= tab_size
.x
;
219 wxCoord tab_x
= in_rect
.x
;
220 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
222 // select pen, brush and font for the tab to be drawn
226 dc
->SetPen(m_selected_bkpen
);
227 dc
->SetBrush(m_selected_bkbrush
);
228 dc
->SetFont(m_selected_font
);
229 textx
= selected_textx
;
230 texty
= selected_texty
;
234 dc
->SetPen(m_normal_bkpen
);
235 dc
->SetBrush(m_normal_bkbrush
);
236 dc
->SetFont(m_normal_font
);
237 textx
= normal_textx
;
238 texty
= normal_texty
;
246 points
[0].y
= tab_y
+ tab_height
- 1;
247 points
[1].x
= tab_x
+ tab_height
- 3;
248 points
[1].y
= tab_y
+ 2;
249 points
[2].x
= tab_x
+ tab_height
+ 3;
251 points
[3].x
= tab_x
+ tab_width
- 2;
253 points
[4].x
= tab_x
+ tab_width
;
254 points
[4].y
= tab_y
+ 2;
255 points
[5].x
= tab_x
+ tab_width
;
256 points
[5].y
= tab_y
+ tab_height
- 1;
257 points
[6] = points
[0];
260 dc
->DrawPolygon(6, points
);
262 dc
->SetPen(*wxGREY_PEN
);
264 //dc->DrawLines(active ? 6 : 7, points);
265 dc
->DrawLines(7, points
);
269 dc
->DrawText(caption
,
270 tab_x
+ (tab_height
/3) + (tab_width
/2) - (textx
/2),
271 (tab_y
+ tab_height
)/2 - (texty
/2) + 1);
273 *out_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
277 wxSize
wxDefaultTabArt::GetTabSize(wxDC
* dc
,
278 const wxString
& caption
,
279 bool WXUNUSED(active
),
282 wxCoord measured_textx
, measured_texty
;
284 dc
->SetFont(m_measuring_font
);
285 dc
->GetTextExtent(caption
, &measured_textx
, &measured_texty
);
287 wxCoord tab_height
= measured_texty
+ 4;
288 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
290 *x_extent
= tab_width
- (tab_height
/2) - 1;
292 return wxSize(tab_width
, tab_height
);
296 void wxDefaultTabArt::DrawButton(
298 const wxRect
& in_rect
,
302 const wxBitmap
& bitmap_override
,
308 if (bitmap_override
.IsOk())
310 bmp
= bitmap_override
;
316 case wxAUI_BUTTON_CLOSE
:
317 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
318 bmp
= m_disabled_close_bmp
;
320 bmp
= m_active_close_bmp
;
322 case wxAUI_BUTTON_LEFT
:
323 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
324 bmp
= m_disabled_left_bmp
;
326 bmp
= m_active_left_bmp
;
328 case wxAUI_BUTTON_RIGHT
:
329 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
330 bmp
= m_disabled_right_bmp
;
332 bmp
= m_active_right_bmp
;
342 if (orientation
== wxLEFT
)
344 rect
.SetX(in_rect
.x
);
345 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
346 rect
.SetWidth(bmp
.GetWidth());
347 rect
.SetHeight(bmp
.GetHeight());
351 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
352 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
353 bmp
.GetWidth(), bmp
.GetHeight());
357 DrawButtonS(*dc
, rect
, bmp
, *wxWHITE
, button_state
);
364 int wxDefaultTabArt::GetBestTabCtrlSize(wxWindow
* wnd
)
367 dc
.SetFont(m_measuring_font
);
369 wxSize s
= GetTabSize(&dc
, wxT("ABCDEFGHIj"), true, &x_ext
);
373 void wxDefaultTabArt::SetNormalFont(const wxFont
& font
)
375 m_normal_font
= font
;
378 void wxDefaultTabArt::SetSelectedFont(const wxFont
& font
)
380 m_selected_font
= font
;
383 void wxDefaultTabArt::SetMeasuringFont(const wxFont
& font
)
385 m_measuring_font
= font
;
393 // -- wxAuiTabContainer class implementation --
396 // wxAuiTabContainer is a class which contains information about each
397 // tab. It also can render an entire tab control to a specified DC.
398 // It's not a window class itself, because this code will be used by
399 // the wxFrameMananger, where it is disadvantageous to have separate
400 // windows for each tab control in the case of "docked tabs"
402 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window
403 // which can be used as a tab control in the normal sense.
406 wxAuiTabContainer::wxAuiTabContainer()
409 m_art
= new wxDefaultTabArt
;
411 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
412 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
413 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
416 wxAuiTabContainer::~wxAuiTabContainer()
421 void wxAuiTabContainer::SetArtProvider(wxTabArt
* art
)
427 wxTabArt
* wxAuiTabContainer::GetArtProvider()
432 void wxAuiTabContainer::SetNormalFont(const wxFont
& font
)
434 m_art
->SetNormalFont(font
);
437 void wxAuiTabContainer::SetSelectedFont(const wxFont
& font
)
439 m_art
->SetSelectedFont(font
);
442 void wxAuiTabContainer::SetMeasuringFont(const wxFont
& font
)
444 m_art
->SetMeasuringFont(font
);
447 void wxAuiTabContainer::SetRect(const wxRect
& rect
)
452 bool wxAuiTabContainer::AddPage(wxWindow
* page
,
453 const wxAuiNotebookPage
& info
)
455 wxAuiNotebookPage page_info
;
457 page_info
.window
= page
;
459 m_pages
.Add(page_info
);
464 bool wxAuiTabContainer::InsertPage(wxWindow
* page
,
465 const wxAuiNotebookPage
& info
,
468 wxAuiNotebookPage page_info
;
470 page_info
.window
= page
;
472 if (idx
>= m_pages
.GetCount())
473 m_pages
.Add(page_info
);
475 m_pages
.Insert(page_info
, idx
);
480 bool wxAuiTabContainer::RemovePage(wxWindow
* wnd
)
482 size_t i
, page_count
= m_pages
.GetCount();
483 for (i
= 0; i
< page_count
; ++i
)
485 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
486 if (page
.window
== wnd
)
496 bool wxAuiTabContainer::SetActivePage(wxWindow
* wnd
)
500 size_t i
, page_count
= m_pages
.GetCount();
501 for (i
= 0; i
< page_count
; ++i
)
503 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
504 if (page
.window
== wnd
)
518 void wxAuiTabContainer::SetNoneActive()
520 size_t i
, page_count
= m_pages
.GetCount();
521 for (i
= 0; i
< page_count
; ++i
)
523 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
528 bool wxAuiTabContainer::SetActivePage(size_t page
)
530 if (page
>= m_pages
.GetCount())
533 return SetActivePage(m_pages
.Item(page
).window
);
536 int wxAuiTabContainer::GetActivePage() const
538 size_t i
, page_count
= m_pages
.GetCount();
539 for (i
= 0; i
< page_count
; ++i
)
541 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
549 wxWindow
* wxAuiTabContainer::GetWindowFromIdx(size_t idx
) const
551 if (idx
>= m_pages
.GetCount())
554 return m_pages
[idx
].window
;
557 int wxAuiTabContainer::GetIdxFromWindow(wxWindow
* wnd
) const
559 size_t i
, page_count
= m_pages
.GetCount();
560 for (i
= 0; i
< page_count
; ++i
)
562 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
563 if (page
.window
== wnd
)
569 wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
)
571 wxASSERT_MSG(idx
< m_pages
.GetCount(), wxT("Invalid Page index"));
576 wxAuiNotebookPageArray
& wxAuiTabContainer::GetPages()
581 size_t wxAuiTabContainer::GetPageCount() const
583 return m_pages
.GetCount();
586 void wxAuiTabContainer::AddButton(int id
,
588 const wxBitmap
& normal_bitmap
,
589 const wxBitmap
& disabled_bitmap
)
591 wxAuiTabContainerButton button
;
593 button
.bitmap
= normal_bitmap
;
594 button
.dis_bitmap
= disabled_bitmap
;
595 button
.location
= location
;
596 button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
598 m_buttons
.Add(button
);
601 size_t wxAuiTabContainer::GetTabOffset() const
606 void wxAuiTabContainer::SetTabOffset(size_t offset
)
608 m_tab_offset
= offset
;
611 // Render() renders the tab catalog to the specified DC
612 // It is a virtual function and can be overridden to
613 // provide custom drawing capabilities
614 void wxAuiTabContainer::Render(wxDC
* raw_dc
)
619 size_t page_count
= m_pages
.GetCount();
620 size_t button_count
= m_buttons
.GetCount();
622 // create off-screen bitmap
623 bmp
.Create(m_rect
.GetWidth(), m_rect
.GetHeight());
624 dc
.SelectObject(bmp
);
627 // find out if size of tabs is larger than can be
628 // afforded on screen
630 int visible_width
= 0;
631 for (i
= 0; i
< page_count
; ++i
)
633 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
635 wxSize size
= m_art
->GetTabSize(&dc
, page
.caption
, page
.active
, &x_extent
);
637 if (i
+1 < page_count
)
638 total_width
+= x_extent
;
640 total_width
+= size
.x
;
642 if (i
>= m_tab_offset
)
644 if (i
+1 < page_count
)
645 visible_width
+= x_extent
;
647 visible_width
+= size
.x
;
651 if (total_width
> m_rect
.GetWidth() - 20 || m_tab_offset
!= 0)
653 // show left/right buttons
654 for (i
= 0; i
< button_count
; ++i
)
656 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
657 if (button
.id
== wxAUI_BUTTON_LEFT
||
658 button
.id
== wxAUI_BUTTON_RIGHT
)
660 button
.cur_state
&= ~wxAUI_BUTTON_STATE_HIDDEN
;
666 // hide left/right buttons
667 for (i
= 0; i
< button_count
; ++i
)
669 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
670 if (button
.id
== wxAUI_BUTTON_LEFT
||
671 button
.id
== wxAUI_BUTTON_RIGHT
)
673 button
.cur_state
|= wxAUI_BUTTON_STATE_HIDDEN
;
678 // determine whether left button should be enabled
679 for (i
= 0; i
< button_count
; ++i
)
681 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
682 if (button
.id
== wxAUI_BUTTON_LEFT
)
684 if (m_tab_offset
== 0)
685 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
687 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
689 if (button
.id
== wxAUI_BUTTON_RIGHT
)
691 if (visible_width
< m_rect
.GetWidth() - ((int)button_count
*16))
692 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
694 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
701 m_art
->DrawBackground(&dc
, m_rect
);
704 int left_buttons_width
= 0;
705 int right_buttons_width
= 0;
709 // draw the buttons on the right side
710 offset
= m_rect
.x
+ m_rect
.width
;
711 for (i
= 0; i
< button_count
; ++i
)
713 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
715 if (button
.location
!= wxRIGHT
)
717 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
720 wxRect button_rect
= m_rect
;
722 button_rect
.SetWidth(offset
);
724 m_art
->DrawButton(&dc
,
732 offset
-= button
.rect
.GetWidth();
733 right_buttons_width
+= button
.rect
.GetWidth();
740 // draw the buttons on the left side
742 for (i
= 0; i
< button_count
; ++i
)
744 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
746 if (button
.location
!= wxLEFT
)
748 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
751 wxRect
button_rect(offset
, 1, 1000, m_rect
.height
);
753 m_art
->DrawButton(&dc
,
761 offset
+= button
.rect
.GetWidth();
762 left_buttons_width
+= button
.rect
.GetWidth();
765 offset
= left_buttons_width
;
768 dc
.SetClippingRegion(left_buttons_width
, 0,
769 m_rect
.GetWidth() - right_buttons_width
- left_buttons_width
- 2,
775 int active_offset
= 0;
778 wxRect rect
= m_rect
;
781 rect
.height
= m_rect
.height
;
783 for (i
= m_tab_offset
; i
< page_count
; ++i
)
785 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
799 active_offset
= offset
;
805 // draw the active tab again so it stands in the foreground
806 if (active
>= m_tab_offset
&& active
< m_pages
.GetCount())
808 wxAuiNotebookPage
& page
= m_pages
.Item(active
);
810 rect
.x
= active_offset
;
819 dc
.DestroyClippingRegion();
821 raw_dc
->Blit(m_rect
.x
, m_rect
.y
,
822 m_rect
.GetWidth(), m_rect
.GetHeight(),
827 // TabHitTest() tests if a tab was hit, passing the window pointer
828 // back if that condition was fulfilled. The function returns
829 // true if a tab was hit, otherwise false
830 bool wxAuiTabContainer::TabHitTest(int x
, int y
, wxWindow
** hit
) const
832 if (!m_rect
.Contains(x
,y
))
835 if (ButtonHitTest(x
, y
, NULL
))
838 size_t i
, page_count
= m_pages
.GetCount();
840 for (i
= m_tab_offset
; i
< page_count
; ++i
)
842 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
843 if (page
.rect
.Contains(x
,y
))
854 // ButtonHitTest() tests if a button was hit. The function returns
855 // true if a button was hit, otherwise false
856 bool wxAuiTabContainer::ButtonHitTest(int x
, int y
,
857 wxAuiTabContainerButton
** hit
) const
859 if (!m_rect
.Contains(x
,y
))
862 size_t i
, button_count
= m_buttons
.GetCount();
864 for (i
= 0; i
< button_count
; ++i
)
866 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
867 if (button
.rect
.Contains(x
,y
))
880 // the utility function ShowWnd() is the same as show,
881 // except it handles wxTabMDIChildFrame windows as well,
882 // as the Show() method on this class is "unplugged"
883 static void ShowWnd(wxWindow
* wnd
, bool show
)
885 if (wnd
->IsKindOf(CLASSINFO(wxTabMDIChildFrame
)))
887 wxTabMDIChildFrame
* cf
= (wxTabMDIChildFrame
*)wnd
;
897 // DoShowHide() this function shows the active window, then
898 // hides all of the other windows (in that order)
899 void wxAuiTabContainer::DoShowHide()
901 wxAuiNotebookPageArray
& pages
= GetPages();
902 size_t i
, page_count
= pages
.GetCount();
904 // show new active page first
905 for (i
= 0; i
< page_count
; ++i
)
907 wxAuiNotebookPage
& page
= pages
.Item(i
);
910 ShowWnd(page
.window
, true);
915 // hide all other pages
916 for (i
= 0; i
< page_count
; ++i
)
918 wxAuiNotebookPage
& page
= pages
.Item(i
);
919 ShowWnd(page
.window
, page
.active
);
928 // -- wxAuiTabCtrl class implementation --
932 BEGIN_EVENT_TABLE(wxAuiTabCtrl
, wxControl
)
933 EVT_PAINT(wxAuiTabCtrl::OnPaint
)
934 EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground
)
935 EVT_SIZE(wxAuiTabCtrl::OnSize
)
936 EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown
)
937 EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp
)
938 EVT_MOTION(wxAuiTabCtrl::OnMotion
)
939 EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow
)
940 EVT_AUINOTEBOOK_BUTTON(-1, wxAuiTabCtrl::OnButton
)
944 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow
* parent
,
948 long style
) : wxControl(parent
, id
, pos
, size
, style
)
950 m_click_pt
= wxDefaultPosition
;
951 m_is_dragging
= false;
952 m_hover_button
= NULL
;
955 wxAuiTabCtrl::~wxAuiTabCtrl()
959 void wxAuiTabCtrl::OnPaint(wxPaintEvent
&)
963 dc
.SetFont(GetFont());
965 if (GetPageCount() > 0)
969 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent
& WXUNUSED(evt
))
973 void wxAuiTabCtrl::OnSize(wxSizeEvent
& evt
)
975 wxSize s
= evt
.GetSize();
976 wxRect
r(0, 0, s
.GetWidth(), s
.GetHeight());
980 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent
& evt
)
983 m_click_pt
= wxDefaultPosition
;
984 m_is_dragging
= false;
988 if (TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
990 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
991 e
.SetSelection(GetIdxFromWindow(wnd
));
992 e
.SetOldSelection(GetActivePage());
993 e
.SetEventObject(this);
994 GetEventHandler()->ProcessEvent(e
);
996 m_click_pt
.x
= evt
.m_x
;
997 m_click_pt
.y
= evt
.m_y
;
998 m_click_tab
= e
.GetSelection();
1003 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_PRESSED
;
1009 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent
&)
1011 if (GetCapture() == this)
1016 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, m_windowId
);
1017 evt
.SetSelection(m_click_tab
);
1018 evt
.SetOldSelection(m_click_tab
);
1019 evt
.SetEventObject(this);
1020 GetEventHandler()->ProcessEvent(evt
);
1026 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_HOVER
;
1030 if (!(m_hover_button
->cur_state
& wxAUI_BUTTON_STATE_DISABLED
))
1032 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, m_windowId
);
1033 evt
.SetInt(m_hover_button
->id
);
1034 evt
.SetEventObject(this);
1035 GetEventHandler()->ProcessEvent(evt
);
1039 m_click_pt
= wxDefaultPosition
;
1040 m_is_dragging
= false;
1044 void wxAuiTabCtrl::OnMotion(wxMouseEvent
& evt
)
1046 wxPoint pos
= evt
.GetPosition();
1048 // check if the mouse is hovering above a button
1049 wxAuiTabContainerButton
* button
;
1050 if (ButtonHitTest(pos
.x
, pos
.y
, &button
))
1052 if (m_hover_button
&& button
!= m_hover_button
)
1054 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1055 m_hover_button
= NULL
;
1060 if (button
->cur_state
!= wxAUI_BUTTON_STATE_HOVER
)
1062 button
->cur_state
= wxAUI_BUTTON_STATE_HOVER
;
1065 m_hover_button
= button
;
1073 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1074 m_hover_button
= NULL
;
1081 if (!evt
.LeftIsDown() || m_click_pt
== wxDefaultPosition
)
1086 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, m_windowId
);
1087 evt
.SetSelection(m_click_tab
);
1088 evt
.SetOldSelection(m_click_tab
);
1089 evt
.SetEventObject(this);
1090 GetEventHandler()->ProcessEvent(evt
);
1095 int drag_x_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_X
);
1096 int drag_y_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_Y
);
1098 if (abs(pos
.x
- m_click_pt
.x
) > drag_x_threshold
||
1099 abs(pos
.y
- m_click_pt
.y
) > drag_y_threshold
)
1101 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, m_windowId
);
1102 evt
.SetSelection(m_click_tab
);
1103 evt
.SetOldSelection(m_click_tab
);
1104 evt
.SetEventObject(this);
1105 GetEventHandler()->ProcessEvent(evt
);
1107 m_is_dragging
= true;
1111 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
))
1115 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1116 m_hover_button
= NULL
;
1122 void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent
& event
)
1124 int button
= event
.GetInt();
1126 if (button
== wxAUI_BUTTON_LEFT
|| button
== wxAUI_BUTTON_RIGHT
)
1128 if (button
== wxAUI_BUTTON_LEFT
)
1130 if (GetTabOffset() > 0)
1132 SetTabOffset(GetTabOffset()-1);
1139 SetTabOffset(GetTabOffset()+1);
1150 // wxTabFrame is an interesting case. It's important that all child pages
1151 // of the multi-notebook control are all actually children of that control
1152 // (and not grandchildren). wxTabFrame facilitates this. There is one
1153 // instance of wxTabFrame for each tab control inside the multi-notebook.
1154 // It's important to know that wxTabFrame is not a real window, but it merely
1155 // used to capture the dimensions/positioning of the internal tab control and
1156 // it's managed page windows
1158 class wxTabFrame
: public wxWindow
1165 m_rect
= wxRect(0,0,200,200);
1166 m_tab_ctrl_height
= 20;
1169 void SetTabCtrlHeight(int h
)
1171 m_tab_ctrl_height
= h
;
1174 void DoSetSize(int x
, int y
,
1175 int width
, int height
,
1176 int WXUNUSED(sizeFlags
= wxSIZE_AUTO
))
1178 m_rect
= wxRect(x
, y
, width
, height
);
1182 void DoGetClientSize(int* x
, int* y
) const
1188 bool Show( bool WXUNUSED(show
= true) ) { return false; }
1195 int tab_height
= wxMin(m_rect
.height
, m_tab_ctrl_height
);
1196 m_tab_rect
= wxRect(m_rect
.x
, m_rect
.y
, m_rect
.width
, tab_height
);
1197 m_tabs
->SetSize(m_rect
.x
, m_rect
.y
, m_rect
.width
, tab_height
);
1198 m_tabs
->SetRect(wxRect(0, 0, m_rect
.width
, tab_height
));
1202 wxAuiNotebookPageArray
& pages
= m_tabs
->GetPages();
1203 size_t i
, page_count
= pages
.GetCount();
1205 for (i
= 0; i
< page_count
; ++i
)
1207 wxAuiNotebookPage
& page
= pages
.Item(i
);
1208 page
.window
->SetSize(m_rect
.x
, m_rect
.y
+tab_height
, m_rect
.width
, m_rect
.height
-tab_height
);
1210 if (page
.window
->IsKindOf(CLASSINFO(wxTabMDIChildFrame
)))
1212 wxTabMDIChildFrame
* wnd
= (wxTabMDIChildFrame
*)page
.window
;
1213 wnd
->ApplyMDIChildFrameRect();
1218 void DoGetSize(int* x
, int* y
) const
1221 *x
= m_rect
.GetWidth();
1223 *y
= m_rect
.GetHeight();
1235 wxAuiTabCtrl
* m_tabs
;
1236 int m_tab_ctrl_height
;
1243 // -- wxAuiMultiNotebook class implementation --
1245 BEGIN_EVENT_TABLE(wxAuiMultiNotebook
, wxControl
)
1246 //EVT_ERASE_BACKGROUND(wxAuiMultiNotebook::OnEraseBackground)
1247 //EVT_SIZE(wxAuiMultiNotebook::OnSize)
1248 //EVT_LEFT_DOWN(wxAuiMultiNotebook::OnLeftDown)
1249 EVT_CHILD_FOCUS(wxAuiMultiNotebook::OnChildFocus
)
1250 EVT_COMMAND_RANGE(10000, 10100,
1251 wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
,
1252 wxAuiMultiNotebook::OnTabClicked
)
1253 EVT_COMMAND_RANGE(10000, 10100,
1254 wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
,
1255 wxAuiMultiNotebook::OnTabBeginDrag
)
1256 EVT_COMMAND_RANGE(10000, 10100,
1257 wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
,
1258 wxAuiMultiNotebook::OnTabEndDrag
)
1259 EVT_COMMAND_RANGE(10000, 10100,
1260 wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
,
1261 wxAuiMultiNotebook::OnTabDragMotion
)
1262 EVT_COMMAND_RANGE(10000, 10100,
1263 wxEVT_COMMAND_AUINOTEBOOK_BUTTON
,
1264 wxAuiMultiNotebook::OnTabButton
)
1267 wxAuiMultiNotebook::wxAuiMultiNotebook()
1270 m_tab_id_counter
= 10000;
1272 m_tab_ctrl_height
= 20;
1275 wxAuiMultiNotebook::wxAuiMultiNotebook(wxWindow
*parent
,
1279 long style
) : wxControl(parent
, id
, pos
, size
, style
)
1284 bool wxAuiMultiNotebook::Create(wxWindow
* parent
,
1290 if (!wxControl::Create(parent
, id
, pos
, size
, style
))
1298 // InitNotebook() contains common initialization
1299 // code called by all constructors
1300 void wxAuiMultiNotebook::InitNotebook()
1303 m_tab_id_counter
= 10000;
1305 m_tab_ctrl_height
= 20;
1307 m_normal_font
= *wxNORMAL_FONT
;
1308 m_selected_font
= *wxNORMAL_FONT
;
1309 m_selected_font
.SetWeight(wxBOLD
);
1311 // choose a default for the tab height
1312 m_tab_ctrl_height
= m_tabs
.GetArtProvider()->GetBestTabCtrlSize(this);
1314 m_dummy_wnd
= new wxWindow(this, wxID_ANY
, wxPoint(0,0), wxSize(0,0));
1315 m_dummy_wnd
->SetSize(200, 200);
1316 m_dummy_wnd
->Show(false);
1318 m_mgr
.SetManagedWindow(this);
1320 m_mgr
.AddPane(m_dummy_wnd
,
1321 wxPaneInfo().Name(wxT("dummy")).Bottom().Show(false));
1326 wxAuiMultiNotebook::~wxAuiMultiNotebook()
1331 void wxAuiMultiNotebook::SetArtProvider(wxTabArt
* art
)
1333 m_tabs
.SetArtProvider(art
);
1336 wxTabArt
* wxAuiMultiNotebook::GetArtProvider()
1338 return m_tabs
.GetArtProvider();
1341 bool wxAuiMultiNotebook::AddPage(wxWindow
* page
,
1342 const wxString
& caption
,
1344 const wxBitmap
& bitmap
)
1346 return InsertPage(GetPageCount(), page
, caption
, select
, bitmap
);
1349 bool wxAuiMultiNotebook::InsertPage(size_t page_idx
,
1351 const wxString
& caption
,
1353 const wxBitmap
& bitmap
)
1355 wxAuiNotebookPage info
;
1357 info
.caption
= caption
;
1358 info
.bitmap
= bitmap
;
1359 info
.active
= false;
1361 // if there are currently no tabs, the first added
1362 // tab must be active
1363 if (m_tabs
.GetPageCount() == 0)
1366 m_tabs
.InsertPage(page
, info
, page_idx
);
1368 wxAuiTabCtrl
* active_tabctrl
= GetActiveTabCtrl();
1369 if (page_idx
>= active_tabctrl
->GetPageCount())
1370 active_tabctrl
->AddPage(page
, info
);
1372 active_tabctrl
->InsertPage(page
, info
, page_idx
);
1375 active_tabctrl
->DoShowHide();
1379 int idx
= m_tabs
.GetIdxFromWindow(page
);
1380 wxASSERT_MSG(idx
!= -1, wxT("Invalid Page index returned on wxAuiMultiNotebook::InsertPage()"));
1389 // DeletePage() removes a tab from the multi-notebook,
1390 // and destroys the window as well
1391 bool wxAuiMultiNotebook::DeletePage(size_t page_idx
)
1393 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
1394 wxWindow
* new_active
= NULL
;
1396 // find out which onscreen tab ctrl owns this tab
1399 if (!FindTab(wnd
, &ctrl
, &ctrl_idx
))
1402 // find a new page and set it as active
1403 int new_idx
= ctrl_idx
+1;
1404 if (new_idx
>= (int)ctrl
->GetPageCount())
1405 new_idx
= ctrl_idx
-1;
1407 if (new_idx
>= 0 && new_idx
< (int)ctrl
->GetPageCount())
1409 new_active
= ctrl
->GetWindowFromIdx(new_idx
);
1413 // set the active page to the first page that
1414 // isn't the one being deleted
1415 size_t i
, page_count
= m_tabs
.GetPageCount();
1416 for (i
= 0; i
< page_count
; ++i
)
1418 wxWindow
* w
= m_tabs
.GetWindowFromIdx(i
);
1421 new_active
= m_tabs
.GetWindowFromIdx(i
);
1427 // remove the tab from main catalog
1428 if (!m_tabs
.RemovePage(wnd
))
1431 // remove the tab from the onscreen tab ctrl
1432 ctrl
->RemovePage(wnd
);
1434 // actually destroy the window now
1435 if (wnd
->IsKindOf(CLASSINFO(wxTabMDIChildFrame
)))
1437 // delete the child frame with pending delete, as is
1438 // customary with frame windows
1439 if (!wxPendingDelete
.Member(wnd
))
1440 wxPendingDelete
.Append(wnd
);
1447 RemoveEmptyTabFrames();
1449 // set new active pane
1453 SetSelection(m_tabs
.GetIdxFromWindow(new_active
));
1461 // RemovePage() removes a tab from the multi-notebook,
1462 // but does not destroy the window
1463 bool wxAuiMultiNotebook::RemovePage(size_t page_idx
)
1465 // remove the tab from our own catalog
1466 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
1467 if (!m_tabs
.RemovePage(wnd
))
1470 // remove the tab from the onscreen tab ctrl
1473 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
1475 ctrl
->RemovePage(wnd
);
1482 // SetPageText() changes the tab caption of the specified page
1483 bool wxAuiMultiNotebook::SetPageText(size_t page_idx
, const wxString
& text
)
1485 if (page_idx
>= m_tabs
.GetPageCount())
1488 // update our own tab catalog
1489 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
1490 page_info
.caption
= text
;
1492 // update what's on screen
1495 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
1497 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
1498 info
.caption
= text
;
1506 // GetSelection() returns the index of the currently active page
1507 int wxAuiMultiNotebook::GetSelection() const
1512 // SetSelection() sets the currently active page
1513 size_t wxAuiMultiNotebook::SetSelection(size_t new_page
)
1515 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(new_page
);
1519 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
1520 evt
.SetSelection(new_page
);
1521 evt
.SetOldSelection(m_curpage
);
1522 evt
.SetEventObject(this);
1523 if (!GetEventHandler()->ProcessEvent(evt
) || evt
.IsAllowed())
1525 // program allows the page change
1526 evt
.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
);
1527 (void)GetEventHandler()->ProcessEvent(evt
);
1533 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
1535 m_tabs
.SetActivePage(wnd
);
1537 ctrl
->SetActivePage(ctrl_idx
);
1541 int old_curpage
= m_curpage
;
1542 m_curpage
= new_page
;
1546 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1547 size_t i
, pane_count
= all_panes
.GetCount();
1548 for (i
= 0; i
< pane_count
; ++i
)
1550 wxPaneInfo
& pane
= all_panes
.Item(i
);
1551 if (pane
.name
== wxT("dummy"))
1553 wxAuiTabCtrl
* tabctrl
= ((wxTabFrame
*)pane
.window
)->m_tabs
;
1554 if (tabctrl
!= ctrl
)
1555 tabctrl
->SetSelectedFont(m_normal_font
);
1557 tabctrl
->SetSelectedFont(m_selected_font
);
1570 // GetPageCount() returns the total number of
1571 // pages managed by the multi-notebook
1572 size_t wxAuiMultiNotebook::GetPageCount() const
1574 return m_tabs
.GetPageCount();
1577 // GetPage() returns the wxWindow pointer of the
1579 wxWindow
* wxAuiMultiNotebook::GetPage(size_t page_idx
) const
1581 wxASSERT(page_idx
< m_tabs
.GetPageCount());
1583 return m_tabs
.GetWindowFromIdx(page_idx
);
1586 // DoSizing() performs all sizing operations in each tab control
1587 void wxAuiMultiNotebook::DoSizing()
1589 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1590 size_t i
, pane_count
= all_panes
.GetCount();
1591 for (i
= 0; i
< pane_count
; ++i
)
1593 if (all_panes
.Item(i
).name
== wxT("dummy"))
1596 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1597 tabframe
->DoSizing();
1601 // GetActiveTabCtrl() returns the active tab control. It is
1602 // called to determine which control gets new windows being added
1603 wxAuiTabCtrl
* wxAuiMultiNotebook::GetActiveTabCtrl()
1605 if (m_curpage
>= 0 && m_curpage
< (int)m_tabs
.GetPageCount())
1610 // find the tab ctrl with the current page
1611 if (FindTab(m_tabs
.GetPage(m_curpage
).window
,
1618 // no current page, just find the first tab ctrl
1619 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1620 size_t i
, pane_count
= all_panes
.GetCount();
1621 for (i
= 0; i
< pane_count
; ++i
)
1623 if (all_panes
.Item(i
).name
== wxT("dummy"))
1626 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1627 return tabframe
->m_tabs
;
1630 // If there is no tabframe at all, create one
1631 wxTabFrame
* tabframe
= new wxTabFrame
;
1632 tabframe
->SetTabCtrlHeight(m_tab_ctrl_height
);
1633 tabframe
->m_tabs
= new wxAuiTabCtrl(this,
1638 m_mgr
.AddPane(tabframe
,
1639 wxPaneInfo().Center().CaptionVisible(false));
1643 return tabframe
->m_tabs
;
1646 // FindTab() finds the tab control that currently contains the window as well
1647 // as the index of the window in the tab control. It returns true if the
1648 // window was found, otherwise false.
1649 bool wxAuiMultiNotebook::FindTab(wxWindow
* page
, wxAuiTabCtrl
** ctrl
, int* idx
)
1651 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1652 size_t i
, pane_count
= all_panes
.GetCount();
1653 for (i
= 0; i
< pane_count
; ++i
)
1655 if (all_panes
.Item(i
).name
== wxT("dummy"))
1658 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1660 int page_idx
= tabframe
->m_tabs
->GetIdxFromWindow(page
);
1663 *ctrl
= tabframe
->m_tabs
;
1673 void wxAuiMultiNotebook::OnEraseBackground(wxEraseEvent
&)
1677 void wxAuiMultiNotebook::OnSize(wxSizeEvent
&)
1681 void wxAuiMultiNotebook::OnTabClicked(wxCommandEvent
& command_evt
)
1683 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
1685 wxAuiTabCtrl
* ctrl
= (wxAuiTabCtrl
*)evt
.GetEventObject();
1686 wxASSERT(ctrl
!= NULL
);
1688 wxWindow
* wnd
= ctrl
->GetWindowFromIdx(evt
.GetSelection());
1689 wxASSERT(wnd
!= NULL
);
1691 int idx
= m_tabs
.GetIdxFromWindow(wnd
);
1692 wxASSERT(idx
!= -1);
1697 void wxAuiMultiNotebook::OnTabBeginDrag(wxCommandEvent
&)
1701 void wxAuiMultiNotebook::OnTabDragMotion(wxCommandEvent
& evt
)
1703 wxPoint screen_pt
= ::wxGetMousePosition();
1704 wxPoint client_pt
= ScreenToClient(screen_pt
);
1707 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
1709 wxAuiTabCtrl
* tab_ctrl
= GetTabCtrlFromPoint(client_pt
);
1710 if (tab_ctrl
== src_tabs
)
1712 // inner-tabctrl dragging is not yet implemented
1719 wxRect hint_rect
= tab_ctrl
->GetRect();
1720 ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
1721 m_mgr
.ShowHint(hint_rect
);
1725 m_mgr
.DrawHintRect(m_dummy_wnd
, client_pt
, zero
);
1731 void wxAuiMultiNotebook::OnTabEndDrag(wxCommandEvent
& command_evt
)
1733 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
1738 // get the mouse position, which will be used to determine the drop point
1739 wxPoint mouse_screen_pt
= ::wxGetMousePosition();
1740 wxPoint mouse_client_pt
= ScreenToClient(mouse_screen_pt
);
1743 // the src tab control is the control that fired this event
1744 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
1745 wxAuiTabCtrl
* dest_tabs
= NULL
;
1748 // If the pointer is in an existing tab frame, do a tab insert
1749 wxWindow
* hit_wnd
= ::wxFindWindowAtPoint(mouse_screen_pt
);
1750 wxTabFrame
* tab_frame
= (wxTabFrame
*)GetTabFrameFromTabCtrl(hit_wnd
);
1753 dest_tabs
= tab_frame
->m_tabs
;
1755 if (dest_tabs
== src_tabs
)
1760 // If there is no tabframe at all, create one
1761 wxTabFrame
* new_tabs
= new wxTabFrame
;
1762 new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
);
1763 new_tabs
->m_tabs
= new wxAuiTabCtrl(this,
1768 m_mgr
.AddPane(new_tabs
,
1769 wxPaneInfo().Bottom().CaptionVisible(false),
1772 dest_tabs
= new_tabs
->m_tabs
;
1777 // remove the page from the source tabs
1778 wxAuiNotebookPage page_info
= src_tabs
->GetPage(evt
.GetSelection());
1779 page_info
.active
= false;
1780 src_tabs
->RemovePage(page_info
.window
);
1781 if (src_tabs
->GetPageCount() > 0)
1783 src_tabs
->SetActivePage((size_t)0);
1784 src_tabs
->DoShowHide();
1785 src_tabs
->Refresh();
1790 // add the page to the destination tabs
1791 dest_tabs
->AddPage(page_info
.window
, page_info
);
1793 if (src_tabs
->GetPageCount() == 0)
1795 RemoveEmptyTabFrames();
1799 dest_tabs
->DoShowHide();
1800 dest_tabs
->Refresh();
1802 SetSelection(m_tabs
.GetIdxFromWindow(page_info
.window
));
1805 wxAuiTabCtrl
* wxAuiMultiNotebook::GetTabCtrlFromPoint(const wxPoint
& pt
)
1807 // if we've just removed the last tab from the source
1808 // tab set, the remove the tab control completely
1809 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1810 size_t i
, pane_count
= all_panes
.GetCount();
1811 for (i
= 0; i
< pane_count
; ++i
)
1813 if (all_panes
.Item(i
).name
== wxT("dummy"))
1816 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1817 if (tabframe
->m_tab_rect
.Contains(pt
))
1818 return tabframe
->m_tabs
;
1824 wxWindow
* wxAuiMultiNotebook::GetTabFrameFromTabCtrl(wxWindow
* tab_ctrl
)
1826 // if we've just removed the last tab from the source
1827 // tab set, the remove the tab control completely
1828 wxPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
1829 size_t i
, pane_count
= all_panes
.GetCount();
1830 for (i
= 0; i
< pane_count
; ++i
)
1832 if (all_panes
.Item(i
).name
== wxT("dummy"))
1835 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1836 if (tabframe
->m_tabs
== tab_ctrl
)
1845 void wxAuiMultiNotebook::RemoveEmptyTabFrames()
1847 // if we've just removed the last tab from the source
1848 // tab set, the remove the tab control completely
1849 wxPaneInfoArray all_panes
= m_mgr
.GetAllPanes();
1850 size_t i
, pane_count
= all_panes
.GetCount();
1851 for (i
= 0; i
< pane_count
; ++i
)
1853 if (all_panes
.Item(i
).name
== wxT("dummy"))
1856 wxTabFrame
* tab_frame
= (wxTabFrame
*)all_panes
.Item(i
).window
;
1857 if (tab_frame
->m_tabs
->GetPageCount() == 0)
1859 m_mgr
.DetachPane(tab_frame
);
1861 // use pending delete because sometimes during
1862 // window closing, refreshs are pending
1863 if (!wxPendingDelete
.Member(tab_frame
->m_tabs
))
1864 wxPendingDelete
.Append(tab_frame
->m_tabs
);
1865 //tab_frame->m_tabs->Destroy();
1872 // check to see if there is still a center pane;
1873 // if there isn't, make a frame the center pane
1874 wxPaneInfoArray panes
= m_mgr
.GetAllPanes();
1875 pane_count
= panes
.GetCount();
1876 wxWindow
* first_good
= NULL
;
1877 bool center_found
= false;
1878 for (i
= 0; i
< pane_count
; ++i
)
1880 if (panes
.Item(i
).name
== wxT("dummy"))
1882 if (panes
.Item(i
).dock_direction
== wxAUI_DOCK_CENTRE
)
1883 center_found
= true;
1885 first_good
= panes
.Item(i
).window
;
1888 if (!center_found
&& first_good
)
1890 m_mgr
.GetPane(first_good
).Centre();
1896 void wxAuiMultiNotebook::OnChildFocus(wxChildFocusEvent
& evt
)
1898 int idx
= m_tabs
.GetIdxFromWindow(evt
.GetWindow());
1899 if (idx
!= -1 && idx
!= m_curpage
)
1906 void wxAuiMultiNotebook::OnTabButton(wxCommandEvent
& command_evt
)
1908 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
1909 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
1911 int button_id
= evt
.GetInt();
1913 if (button_id
== wxAUI_BUTTON_CLOSE
)
1915 int selection
= tabs
->GetActivePage();
1917 if (selection
!= -1)
1919 wxWindow
* close_wnd
= tabs
->GetWindowFromIdx(selection
);
1921 if (close_wnd
->IsKindOf(CLASSINFO(wxTabMDIChildFrame
)))
1927 int main_idx
= m_tabs
.GetIdxFromWindow(close_wnd
);
1928 DeletePage(main_idx
);