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"
35 #include "wx/mac/carbon/private.h"
38 #include "wx/arrimpl.cpp"
39 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray
)
40 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray
)
42 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
)
43 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
)
44 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
)
45 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
)
46 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
)
47 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
)
48 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
)
49 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
)
52 IMPLEMENT_CLASS(wxAuiNotebook
, wxControl
)
53 IMPLEMENT_CLASS(wxAuiTabCtrl
, wxControl
)
54 IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent
, wxEvent
)
60 // these functions live in dockart.cpp -- they'll eventually
61 // be moved to a new utility cpp file
63 wxColor
wxAuiStepColour(const wxColor
& c
, int percent
);
65 wxBitmap
wxAuiBitmapFromBits(const unsigned char bits
[], int w
, int h
,
66 const wxColour
& color
);
68 wxString
wxAuiChopText(wxDC
& dc
, const wxString
& text
, int max_size
);
70 static void DrawButtons(wxDC
& dc
,
73 const wxColour
& bkcolour
,
78 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
84 if (button_state
== wxAUI_BUTTON_STATE_HOVER
||
85 button_state
== wxAUI_BUTTON_STATE_PRESSED
)
87 dc
.SetBrush(wxBrush(wxAuiStepColour(bkcolour
, 120)));
88 dc
.SetPen(wxPen(wxAuiStepColour(bkcolour
, 70)));
90 // draw the background behind the button
91 dc
.DrawRectangle(rect
.x
, rect
.y
, 15, 15);
94 // draw the button itself
95 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
98 static void IndentPressedBitmap(wxRect
* rect
, int button_state
)
100 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
109 // -- GUI helper classes and functions --
111 class wxAuiCommandCapture
: public wxEvtHandler
115 wxAuiCommandCapture() { m_last_id
= 0; }
116 int GetCommandId() const { return m_last_id
; }
118 bool ProcessEvent(wxEvent
& evt
)
120 if (evt
.GetEventType() == wxEVT_COMMAND_MENU_SELECTED
)
122 m_last_id
= evt
.GetId();
126 if (GetNextHandler())
127 return GetNextHandler()->ProcessEvent(evt
);
139 #if defined( __WXMAC__ )
140 static unsigned char close_bits
[]={
141 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
142 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
143 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
144 #elif defined( __WXGTK__)
145 static unsigned char close_bits
[]={
146 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
147 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
148 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
150 static unsigned char close_bits
[]={
151 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9,
152 0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3,
153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
156 static unsigned char left_bits
[] = {
157 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
158 0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
159 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
161 static unsigned char right_bits
[] = {
162 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
163 0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
164 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
166 static unsigned char list_bits
[] = {
167 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
168 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff,
169 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
176 // -- wxAuiDefaultTabArt class implementation --
178 wxAuiDefaultTabArt::wxAuiDefaultTabArt()
180 m_normal_font
= *wxNORMAL_FONT
;
181 m_selected_font
= *wxNORMAL_FONT
;
182 m_selected_font
.SetWeight(wxBOLD
);
183 m_measuring_font
= m_selected_font
;
185 m_fixed_tab_width
= 100;
186 m_tab_ctrl_height
= 0;
189 wxBrush toolbarbrush
;
190 toolbarbrush
.MacSetTheme( kThemeBrushToolbarBackground
);
191 wxColor base_colour
= toolbarbrush
.GetColour();
193 wxColor base_colour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
196 m_base_colour
= base_colour
;
197 wxColor darker2_colour
= wxAuiStepColour(base_colour
, 70);
199 m_border_pen
= wxPen(darker2_colour
);
200 m_base_colour_pen
= wxPen(m_base_colour
);
201 m_base_colour_brush
= wxBrush(m_base_colour
);
203 m_active_close_bmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
204 m_disabled_close_bmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
206 m_active_left_bmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
207 m_disabled_left_bmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
209 m_active_right_bmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
210 m_disabled_right_bmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
212 m_active_windowlist_bmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
213 m_disabled_windowlist_bmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
218 wxAuiDefaultTabArt::~wxAuiDefaultTabArt()
222 wxAuiTabArt
* wxAuiDefaultTabArt::Clone()
224 return static_cast<wxAuiTabArt
*>(new wxAuiDefaultTabArt
);
227 void wxAuiDefaultTabArt::SetFlags(unsigned int flags
)
232 void wxAuiDefaultTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
235 m_fixed_tab_width
= 100;
237 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
239 if (m_flags
& wxAUI_NB_CLOSE_BUTTON
)
240 tot_width
-= m_active_close_bmp
.GetWidth();
241 if (m_flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
242 tot_width
-= m_active_windowlist_bmp
.GetWidth();
246 m_fixed_tab_width
= tot_width
/(int)tab_count
;
250 if (m_fixed_tab_width
< 100)
251 m_fixed_tab_width
= 100;
253 if (m_fixed_tab_width
> tot_width
/2)
254 m_fixed_tab_width
= tot_width
/2;
256 if (m_fixed_tab_width
> 220)
257 m_fixed_tab_width
= 220;
259 m_tab_ctrl_height
= tab_ctrl_size
.y
;
263 void wxAuiDefaultTabArt::DrawBackground(wxDC
& dc
,
264 wxWindow
* WXUNUSED(wnd
),
268 wxRect
r(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
-3);
269 wxColor top_color
= wxAuiStepColour(m_base_colour
, 90);
270 wxColor bottom_color
= wxAuiStepColour(m_base_colour
, 110);
271 dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
);
274 int y
= rect
.GetHeight();
275 int w
= rect
.GetWidth();
276 dc
.SetPen(m_border_pen
);
277 dc
.SetBrush(m_base_colour_brush
);
278 dc
.DrawRectangle(-1, y
-4, w
+2, 4);
282 // DrawTab() draws an individual tab.
285 // in_rect - rectangle the tab should be confined to
286 // caption - tab's caption
287 // active - whether or not the tab is active
288 // out_rect - actual output rectangle
289 // x_extent - the advance x; where the next tab should start
291 void wxAuiDefaultTabArt::DrawTab(wxDC
& dc
,
293 const wxRect
& in_rect
,
294 const wxString
& caption_text
,
295 const wxBitmap
& bitmap
,
297 int close_button_state
,
298 wxRect
* out_tab_rect
,
299 wxRect
* out_button_rect
,
302 wxCoord normal_textx
, normal_texty
;
303 wxCoord selected_textx
, selected_texty
;
304 wxCoord textx
, texty
;
306 // if the caption is empty, measure some temporary text
307 wxString caption
= caption_text
;
308 if (caption_text
.empty())
311 dc
.SetFont(m_selected_font
);
312 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
314 dc
.SetFont(m_normal_font
);
315 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
317 // figure out the size of the tab
318 wxSize tab_size
= GetTabSize(dc
,
326 wxCoord tab_height
= m_tab_ctrl_height
- 3;
327 wxCoord tab_width
= tab_size
.x
;
328 wxCoord tab_x
= in_rect
.x
;
329 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
332 caption
= caption_text
;
335 // select pen, brush and font for the tab to be drawn
339 dc
.SetFont(m_selected_font
);
340 textx
= selected_textx
;
341 texty
= selected_texty
;
345 dc
.SetFont(m_normal_font
);
346 textx
= normal_textx
;
347 texty
= normal_texty
;
351 // create points that will make the tab outline
353 int clip_width
= tab_width
;
354 if (tab_x
+ clip_width
> in_rect
.x
+ in_rect
.width
)
355 clip_width
= (in_rect
.x
+ in_rect
.width
) - tab_x
;
357 wxPoint clip_points
[6];
358 clip_points
[0] = wxPoint(tab_x
, tab_y
+tab_height
-3);
359 clip_points
[1] = wxPoint(tab_x
, tab_y
+2);
360 clip_points
[2] = wxPoint(tab_x
+2, tab_y
);
361 clip_points
[3] = wxPoint(tab_x
+clip_width
-1, tab_y
);
362 clip_points
[4] = wxPoint(tab_x
+clip_width
+1, tab_y
+2);
363 clip_points
[5] = wxPoint(tab_x
+clip_width
+1, tab_y
+tab_height
-3);
365 // FIXME: these ports don't provide wxRegion ctor from array of points
366 #if !defined(__WXDFB__) && !defined(__WXCOCOA__)
367 // set the clipping region for the tab --
368 wxRegion
clipping_region(WXSIZEOF(clip_points
), clip_points
);
369 dc
.SetClippingRegion(clipping_region
);
370 #endif // !wxDFB && !wxCocoa
372 wxPoint border_points
[6];
373 border_points
[0] = wxPoint(tab_x
, tab_y
+tab_height
-4);
374 border_points
[1] = wxPoint(tab_x
, tab_y
+2);
375 border_points
[2] = wxPoint(tab_x
+2, tab_y
);
376 border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
);
377 border_points
[4] = wxPoint(tab_x
+tab_width
, tab_y
+2);
378 border_points
[5] = wxPoint(tab_x
+tab_width
, tab_y
+tab_height
-4);
381 int drawn_tab_yoff
= border_points
[1].y
;
382 int drawn_tab_height
= border_points
[0].y
- border_points
[1].y
;
389 // draw base background color
390 wxRect
r(tab_x
, tab_y
, tab_width
, tab_height
);
391 dc
.SetPen(m_base_colour_pen
);
392 dc
.SetBrush(m_base_colour_brush
);
393 dc
.DrawRectangle(r
.x
, r
.y
, r
.width
, r
.height
);
395 // this white helps fill out the gradient at the top of the tab
396 dc
.SetPen(*wxWHITE_PEN
);
397 dc
.SetBrush(*wxWHITE_BRUSH
);
398 dc
.DrawRectangle(r
.x
+2, r
.y
+1, r
.width
-3, r
.height
);
400 // these two points help the rounded corners appear more antialiased
401 dc
.SetPen(m_base_colour_pen
);
402 dc
.DrawPoint(r
.x
+2, r
.y
+1);
403 dc
.DrawPoint(r
.x
+r
.width
-2, r
.y
+1);
405 // set rectangle down a bit for gradient drawing
406 r
.SetHeight(r
.GetHeight()/2);
412 // draw gradient background
413 wxColor top_color
= *wxWHITE
;
414 wxColor bottom_color
= m_base_colour
;
415 dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
);
421 wxRect
r(tab_x
, tab_y
+1, tab_width
, tab_height
-3);
423 // start the gradent up a bit and leave the inside border inset
424 // by a pixel for a 3D look. Only the top half of the inactive
425 // tab will have a slight gradient
432 // -- draw top gradient fill for glossy look
433 wxColor top_color
= m_base_colour
;
434 wxColor bottom_color
= wxAuiStepColour(top_color
, 106);
435 dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
);
440 // -- draw bottom fill for glossy look
441 top_color
= m_base_colour
;
442 bottom_color
= m_base_colour
;
443 dc
.GradientFillLinear(r
, top_color
, bottom_color
, wxSOUTH
);
447 dc
.SetPen(m_border_pen
);
448 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
449 dc
.DrawPolygon(WXSIZEOF(border_points
), border_points
);
451 // there are two horizontal grey lines at the bottom of the tab control,
452 // this gets rid of the top one of those lines in the tab control
455 wxColor start_color
= m_base_colour
;
456 dc
.SetPen(m_base_colour_pen
);
457 dc
.DrawLine(border_points
[0].x
+1,
464 int text_offset
= tab_x
+ 8;
465 int close_button_width
= 0;
466 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
468 close_button_width
= m_active_close_bmp
.GetWidth();
474 int bitmap_offset
= tab_x
+ 8;
477 dc
.DrawBitmap(bitmap
,
479 drawn_tab_yoff
+ (drawn_tab_height
/2) - (bitmap
.GetHeight()/2) + 1,
482 text_offset
= bitmap_offset
+ bitmap
.GetWidth();
483 text_offset
+= 3; // bitmap padding
487 text_offset
= tab_x
+ 8;
491 wxString draw_text
= wxAuiChopText(dc
,
493 tab_width
- (text_offset
-tab_x
) - close_button_width
);
496 dc
.DrawText(draw_text
,
498 drawn_tab_yoff
+ (drawn_tab_height
)/2 - (texty
/2) - 1);
503 // draw close button if necessary
504 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
506 wxBitmap bmp
= m_disabled_close_bmp
;
508 if (close_button_state
== wxAUI_BUTTON_STATE_HOVER
||
509 close_button_state
== wxAUI_BUTTON_STATE_PRESSED
)
511 bmp
= m_active_close_bmp
;
514 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
515 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2),
518 IndentPressedBitmap(&rect
, close_button_state
);
519 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
521 *out_button_rect
= rect
;
524 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
526 dc
.DestroyClippingRegion();
529 int wxAuiDefaultTabArt::GetIndentSize()
534 wxSize
wxAuiDefaultTabArt::GetTabSize(wxDC
& dc
,
535 wxWindow
* WXUNUSED(wnd
),
536 const wxString
& caption
,
537 const wxBitmap
& bitmap
,
538 bool WXUNUSED(active
),
539 int close_button_state
,
542 wxCoord measured_textx
, measured_texty
, tmp
;
544 dc
.SetFont(m_measuring_font
);
545 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
547 dc
.GetTextExtent(wxT("ABCDEFXj"), &tmp
, &measured_texty
);
549 // add padding around the text
550 wxCoord tab_width
= measured_textx
;
551 wxCoord tab_height
= measured_texty
;
553 // if the close button is showing, add space for it
554 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
555 tab_width
+= m_active_close_bmp
.GetWidth() + 3;
557 // if there's a bitmap, add space for it
560 tab_width
+= bitmap
.GetWidth();
561 tab_width
+= 3; // right side bitmap padding
562 tab_height
= wxMax(tab_height
, bitmap
.GetHeight());
569 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
571 tab_width
= m_fixed_tab_width
;
574 *x_extent
= tab_width
;
576 return wxSize(tab_width
, tab_height
);
580 void wxAuiDefaultTabArt::DrawButton(wxDC
& dc
,
581 wxWindow
* WXUNUSED(wnd
),
582 const wxRect
& in_rect
,
586 const wxBitmap
& bitmap_override
,
592 if (bitmap_override
.IsOk())
594 bmp
= bitmap_override
;
600 case wxAUI_BUTTON_CLOSE
:
601 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
602 bmp
= m_disabled_close_bmp
;
604 bmp
= m_active_close_bmp
;
606 case wxAUI_BUTTON_LEFT
:
607 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
608 bmp
= m_disabled_left_bmp
;
610 bmp
= m_active_left_bmp
;
612 case wxAUI_BUTTON_RIGHT
:
613 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
614 bmp
= m_disabled_right_bmp
;
616 bmp
= m_active_right_bmp
;
618 case wxAUI_BUTTON_WINDOWLIST
:
619 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
620 bmp
= m_disabled_windowlist_bmp
;
622 bmp
= m_active_windowlist_bmp
;
632 if (orientation
== wxLEFT
)
634 rect
.SetX(in_rect
.x
);
635 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
636 rect
.SetWidth(bmp
.GetWidth());
637 rect
.SetHeight(bmp
.GetHeight());
641 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
642 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
643 bmp
.GetWidth(), bmp
.GetHeight());
646 IndentPressedBitmap(&rect
, button_state
);
647 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
653 int wxAuiDefaultTabArt::ShowWindowList(wxWindow
* wnd
,
654 const wxArrayString
& items
,
659 size_t i
, count
= items
.GetCount();
660 for (i
= 0; i
< count
; ++i
)
662 menuPopup
.AppendCheckItem(1000+i
, items
.Item(i
));
665 if (active_idx
!= -1)
667 menuPopup
.Check(1000+active_idx
, true);
670 // find out where to put the popup menu of window
671 // items. Subtract 100 for now to center the menu
672 // a bit, until a better mechanism can be implemented
673 wxPoint pt
= ::wxGetMousePosition();
674 pt
= wnd
->ScreenToClient(pt
);
680 // find out the screen coordinate at the bottom of the tab ctrl
681 wxRect cli_rect
= wnd
->GetClientRect();
682 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
684 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
685 wnd
->PushEventHandler(cc
);
686 wnd
->PopupMenu(&menuPopup
, pt
);
687 int command
= cc
->GetCommandId();
688 wnd
->PopEventHandler(true);
696 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
697 wxAuiNotebookPageArray
& pages
,
698 const wxSize
& required_bmp_size
)
701 dc
.SetFont(m_measuring_font
);
703 // sometimes a standard bitmap size needs to be enforced, especially
704 // if some tabs have bitmaps and others don't. This is important because
705 // it prevents the tab control from resizing when tabs are added.
706 wxBitmap measure_bmp
;
707 if (required_bmp_size
.IsFullySpecified())
709 measure_bmp
.Create(required_bmp_size
.x
,
710 required_bmp_size
.y
);
715 size_t i
, page_count
= pages
.GetCount();
716 for (i
= 0; i
< page_count
; ++i
)
718 wxAuiNotebookPage
& page
= pages
.Item(i
);
721 if (measure_bmp
.IsOk())
726 // we don't use the caption text because we don't
727 // want tab heights to be different in the case
728 // of a very short piece of text on one tab and a very
729 // tall piece of text on another tab
731 wxSize s
= GetTabSize(dc
,
736 wxAUI_BUTTON_STATE_HIDDEN
,
739 max_y
= wxMax(max_y
, s
.y
);
745 void wxAuiDefaultTabArt::SetNormalFont(const wxFont
& font
)
747 m_normal_font
= font
;
750 void wxAuiDefaultTabArt::SetSelectedFont(const wxFont
& font
)
752 m_selected_font
= font
;
755 void wxAuiDefaultTabArt::SetMeasuringFont(const wxFont
& font
)
757 m_measuring_font
= font
;
761 // -- wxAuiSimpleTabArt class implementation --
763 wxAuiSimpleTabArt::wxAuiSimpleTabArt()
765 m_normal_font
= *wxNORMAL_FONT
;
766 m_selected_font
= *wxNORMAL_FONT
;
767 m_selected_font
.SetWeight(wxBOLD
);
768 m_measuring_font
= m_selected_font
;
771 m_fixed_tab_width
= 100;
773 wxColour base_colour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
775 wxColour background_colour
= wxAuiStepColour(base_colour
, 95);
776 wxColour normaltab_colour
= base_colour
;
777 wxColour selectedtab_colour
= *wxWHITE
;
779 m_bkbrush
= wxBrush(background_colour
);
780 m_normal_bkbrush
= wxBrush(normaltab_colour
);
781 m_normal_bkpen
= wxPen(normaltab_colour
);
782 m_selected_bkbrush
= wxBrush(selectedtab_colour
);
783 m_selected_bkpen
= wxPen(selectedtab_colour
);
785 m_active_close_bmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
786 m_disabled_close_bmp
= wxAuiBitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
788 m_active_left_bmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
789 m_disabled_left_bmp
= wxAuiBitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
791 m_active_right_bmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
792 m_disabled_right_bmp
= wxAuiBitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
794 m_active_windowlist_bmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
795 m_disabled_windowlist_bmp
= wxAuiBitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
799 wxAuiSimpleTabArt::~wxAuiSimpleTabArt()
803 wxAuiTabArt
* wxAuiSimpleTabArt::Clone()
805 return static_cast<wxAuiTabArt
*>(new wxAuiSimpleTabArt
);
809 void wxAuiSimpleTabArt::SetFlags(unsigned int flags
)
814 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
817 m_fixed_tab_width
= 100;
819 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
821 if (m_flags
& wxAUI_NB_CLOSE_BUTTON
)
822 tot_width
-= m_active_close_bmp
.GetWidth();
823 if (m_flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
824 tot_width
-= m_active_windowlist_bmp
.GetWidth();
828 m_fixed_tab_width
= tot_width
/(int)tab_count
;
832 if (m_fixed_tab_width
< 100)
833 m_fixed_tab_width
= 100;
835 if (m_fixed_tab_width
> tot_width
/2)
836 m_fixed_tab_width
= tot_width
/2;
838 if (m_fixed_tab_width
> 220)
839 m_fixed_tab_width
= 220;
842 void wxAuiSimpleTabArt::DrawBackground(wxDC
& dc
,
843 wxWindow
* WXUNUSED(wnd
),
847 dc
.SetBrush(m_bkbrush
);
848 dc
.SetPen(*wxTRANSPARENT_PEN
);
849 dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2);
852 dc
.SetPen(*wxGREY_PEN
);
853 dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1);
857 // DrawTab() draws an individual tab.
860 // in_rect - rectangle the tab should be confined to
861 // caption - tab's caption
862 // active - whether or not the tab is active
863 // out_rect - actual output rectangle
864 // x_extent - the advance x; where the next tab should start
866 void wxAuiSimpleTabArt::DrawTab(wxDC
& dc
,
868 const wxRect
& in_rect
,
869 const wxString
& caption_text
,
870 const wxBitmap
& bitmap
,
872 int close_button_state
,
873 wxRect
* out_tab_rect
,
874 wxRect
* out_button_rect
,
877 wxCoord normal_textx
, normal_texty
;
878 wxCoord selected_textx
, selected_texty
;
879 wxCoord textx
, texty
;
881 // if the caption is empty, measure some temporary text
882 wxString caption
= caption_text
;
883 if (caption_text
.empty())
886 dc
.SetFont(m_selected_font
);
887 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
889 dc
.SetFont(m_normal_font
);
890 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
892 // figure out the size of the tab
893 wxSize tab_size
= GetTabSize(dc
,
901 wxCoord tab_height
= tab_size
.y
;
902 wxCoord tab_width
= tab_size
.x
;
903 wxCoord tab_x
= in_rect
.x
;
904 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
906 caption
= caption_text
;
908 // select pen, brush and font for the tab to be drawn
912 dc
.SetPen(m_selected_bkpen
);
913 dc
.SetBrush(m_selected_bkbrush
);
914 dc
.SetFont(m_selected_font
);
915 textx
= selected_textx
;
916 texty
= selected_texty
;
920 dc
.SetPen(m_normal_bkpen
);
921 dc
.SetBrush(m_normal_bkbrush
);
922 dc
.SetFont(m_normal_font
);
923 textx
= normal_textx
;
924 texty
= normal_texty
;
932 points
[0].y
= tab_y
+ tab_height
- 1;
933 points
[1].x
= tab_x
+ tab_height
- 3;
934 points
[1].y
= tab_y
+ 2;
935 points
[2].x
= tab_x
+ tab_height
+ 3;
937 points
[3].x
= tab_x
+ tab_width
- 2;
939 points
[4].x
= tab_x
+ tab_width
;
940 points
[4].y
= tab_y
+ 2;
941 points
[5].x
= tab_x
+ tab_width
;
942 points
[5].y
= tab_y
+ tab_height
- 1;
943 points
[6] = points
[0];
945 dc
.SetClippingRegion(in_rect
);
947 dc
.DrawPolygon(WXSIZEOF(points
) - 1, points
);
949 dc
.SetPen(*wxGREY_PEN
);
951 //dc.DrawLines(active ? WXSIZEOF(points) - 1 : WXSIZEOF(points), points);
952 dc
.DrawLines(WXSIZEOF(points
), points
);
957 int close_button_width
= 0;
958 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
960 close_button_width
= m_active_close_bmp
.GetWidth();
961 text_offset
= tab_x
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2);
965 text_offset
= tab_x
+ (tab_height
/3) + (tab_width
/2) - (textx
/2);
968 // set minimum text offset
969 if (text_offset
< tab_x
+ tab_height
)
970 text_offset
= tab_x
+ tab_height
;
972 // chop text if necessary
973 wxString draw_text
= wxAuiChopText(dc
,
975 tab_width
- (text_offset
-tab_x
) - close_button_width
);
978 dc
.DrawText(draw_text
,
980 (tab_y
+ tab_height
)/2 - (texty
/2) + 1);
983 // draw close button if necessary
984 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
988 bmp
= m_active_close_bmp
;
990 bmp
= m_disabled_close_bmp
;
992 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
993 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1,
996 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, close_button_state
);
998 *out_button_rect
= rect
;
1002 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
1004 dc
.DestroyClippingRegion();
1007 int wxAuiSimpleTabArt::GetIndentSize()
1012 wxSize
wxAuiSimpleTabArt::GetTabSize(wxDC
& dc
,
1013 wxWindow
* WXUNUSED(wnd
),
1014 const wxString
& caption
,
1015 const wxBitmap
& WXUNUSED(bitmap
),
1016 bool WXUNUSED(active
),
1017 int close_button_state
,
1020 wxCoord measured_textx
, measured_texty
;
1022 dc
.SetFont(m_measuring_font
);
1023 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
1025 wxCoord tab_height
= measured_texty
+ 4;
1026 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
1028 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1029 tab_width
+= m_active_close_bmp
.GetWidth();
1031 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
1033 tab_width
= m_fixed_tab_width
;
1036 *x_extent
= tab_width
- (tab_height
/2) - 1;
1038 return wxSize(tab_width
, tab_height
);
1042 void wxAuiSimpleTabArt::DrawButton(wxDC
& dc
,
1043 wxWindow
* WXUNUSED(wnd
),
1044 const wxRect
& in_rect
,
1048 const wxBitmap
& bitmap_override
,
1054 if (bitmap_override
.IsOk())
1056 bmp
= bitmap_override
;
1062 case wxAUI_BUTTON_CLOSE
:
1063 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1064 bmp
= m_disabled_close_bmp
;
1066 bmp
= m_active_close_bmp
;
1068 case wxAUI_BUTTON_LEFT
:
1069 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1070 bmp
= m_disabled_left_bmp
;
1072 bmp
= m_active_left_bmp
;
1074 case wxAUI_BUTTON_RIGHT
:
1075 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1076 bmp
= m_disabled_right_bmp
;
1078 bmp
= m_active_right_bmp
;
1080 case wxAUI_BUTTON_WINDOWLIST
:
1081 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1082 bmp
= m_disabled_windowlist_bmp
;
1084 bmp
= m_active_windowlist_bmp
;
1094 if (orientation
== wxLEFT
)
1096 rect
.SetX(in_rect
.x
);
1097 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
1098 rect
.SetWidth(bmp
.GetWidth());
1099 rect
.SetHeight(bmp
.GetHeight());
1103 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
1104 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
1105 bmp
.GetWidth(), bmp
.GetHeight());
1109 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, button_state
);
1115 int wxAuiSimpleTabArt::ShowWindowList(wxWindow
* wnd
,
1116 const wxArrayString
& items
,
1121 size_t i
, count
= items
.GetCount();
1122 for (i
= 0; i
< count
; ++i
)
1124 menuPopup
.AppendCheckItem(1000+i
, items
.Item(i
));
1127 if (active_idx
!= -1)
1129 menuPopup
.Check(1000+active_idx
, true);
1132 // find out where to put the popup menu of window
1133 // items. Subtract 100 for now to center the menu
1134 // a bit, until a better mechanism can be implemented
1135 wxPoint pt
= ::wxGetMousePosition();
1136 pt
= wnd
->ScreenToClient(pt
);
1142 // find out the screen coordinate at the bottom of the tab ctrl
1143 wxRect cli_rect
= wnd
->GetClientRect();
1144 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
1146 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
1147 wnd
->PushEventHandler(cc
);
1148 wnd
->PopupMenu(&menuPopup
, pt
);
1149 int command
= cc
->GetCommandId();
1150 wnd
->PopEventHandler(true);
1152 if (command
>= 1000)
1153 return command
-1000;
1158 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
1159 wxAuiNotebookPageArray
& WXUNUSED(pages
),
1160 const wxSize
& WXUNUSED(required_bmp_size
))
1163 dc
.SetFont(m_measuring_font
);
1165 wxSize s
= GetTabSize(dc
,
1170 wxAUI_BUTTON_STATE_HIDDEN
,
1175 void wxAuiSimpleTabArt::SetNormalFont(const wxFont
& font
)
1177 m_normal_font
= font
;
1180 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont
& font
)
1182 m_selected_font
= font
;
1185 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont
& font
)
1187 m_measuring_font
= font
;
1193 // -- wxAuiTabContainer class implementation --
1196 // wxAuiTabContainer is a class which contains information about each
1197 // tab. It also can render an entire tab control to a specified DC.
1198 // It's not a window class itself, because this code will be used by
1199 // the wxFrameMananger, where it is disadvantageous to have separate
1200 // windows for each tab control in the case of "docked tabs"
1202 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window
1203 // which can be used as a tab control in the normal sense.
1206 wxAuiTabContainer::wxAuiTabContainer()
1210 m_art
= new wxAuiDefaultTabArt
;
1212 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
1213 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
1214 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
1215 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
1218 wxAuiTabContainer::~wxAuiTabContainer()
1223 void wxAuiTabContainer::SetArtProvider(wxAuiTabArt
* art
)
1230 m_art
->SetFlags(m_flags
);
1234 wxAuiTabArt
* wxAuiTabContainer::GetArtProvider() const
1239 void wxAuiTabContainer::SetFlags(unsigned int flags
)
1243 // check for new close button settings
1244 RemoveButton(wxAUI_BUTTON_LEFT
);
1245 RemoveButton(wxAUI_BUTTON_RIGHT
);
1246 RemoveButton(wxAUI_BUTTON_WINDOWLIST
);
1247 RemoveButton(wxAUI_BUTTON_CLOSE
);
1250 if (flags
& wxAUI_NB_SCROLL_BUTTONS
)
1252 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
1253 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
1256 if (flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
1258 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
1261 if (flags
& wxAUI_NB_CLOSE_BUTTON
)
1263 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
1268 m_art
->SetFlags(m_flags
);
1272 unsigned int wxAuiTabContainer::GetFlags() const
1278 void wxAuiTabContainer::SetNormalFont(const wxFont
& font
)
1280 m_art
->SetNormalFont(font
);
1283 void wxAuiTabContainer::SetSelectedFont(const wxFont
& font
)
1285 m_art
->SetSelectedFont(font
);
1288 void wxAuiTabContainer::SetMeasuringFont(const wxFont
& font
)
1290 m_art
->SetMeasuringFont(font
);
1293 void wxAuiTabContainer::SetRect(const wxRect
& rect
)
1299 m_art
->SetSizingInfo(rect
.GetSize(), m_pages
.GetCount());
1303 bool wxAuiTabContainer::AddPage(wxWindow
* page
,
1304 const wxAuiNotebookPage
& info
)
1306 wxAuiNotebookPage page_info
;
1308 page_info
.window
= page
;
1310 m_pages
.Add(page_info
);
1312 // let the art provider know how many pages we have
1315 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1321 bool wxAuiTabContainer::InsertPage(wxWindow
* page
,
1322 const wxAuiNotebookPage
& info
,
1325 wxAuiNotebookPage page_info
;
1327 page_info
.window
= page
;
1329 if (idx
>= m_pages
.GetCount())
1330 m_pages
.Add(page_info
);
1332 m_pages
.Insert(page_info
, idx
);
1334 // let the art provider know how many pages we have
1337 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1343 bool wxAuiTabContainer::MovePage(wxWindow
* page
,
1346 int idx
= GetIdxFromWindow(page
);
1350 // get page entry, make a copy of it
1351 wxAuiNotebookPage p
= GetPage(idx
);
1353 // remove old page entry
1356 // insert page where it should be
1357 InsertPage(page
, p
, new_idx
);
1362 bool wxAuiTabContainer::RemovePage(wxWindow
* wnd
)
1364 size_t i
, page_count
= m_pages
.GetCount();
1365 for (i
= 0; i
< page_count
; ++i
)
1367 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1368 if (page
.window
== wnd
)
1370 m_pages
.RemoveAt(i
);
1372 // let the art provider know how many pages we have
1375 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1385 bool wxAuiTabContainer::SetActivePage(wxWindow
* wnd
)
1389 size_t i
, page_count
= m_pages
.GetCount();
1390 for (i
= 0; i
< page_count
; ++i
)
1392 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1393 if (page
.window
== wnd
)
1400 page
.active
= false;
1407 void wxAuiTabContainer::SetNoneActive()
1409 size_t i
, page_count
= m_pages
.GetCount();
1410 for (i
= 0; i
< page_count
; ++i
)
1412 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1413 page
.active
= false;
1417 bool wxAuiTabContainer::SetActivePage(size_t page
)
1419 if (page
>= m_pages
.GetCount())
1422 return SetActivePage(m_pages
.Item(page
).window
);
1425 int wxAuiTabContainer::GetActivePage() const
1427 size_t i
, page_count
= m_pages
.GetCount();
1428 for (i
= 0; i
< page_count
; ++i
)
1430 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1438 wxWindow
* wxAuiTabContainer::GetWindowFromIdx(size_t idx
) const
1440 if (idx
>= m_pages
.GetCount())
1443 return m_pages
[idx
].window
;
1446 int wxAuiTabContainer::GetIdxFromWindow(wxWindow
* wnd
) const
1448 size_t i
, page_count
= m_pages
.GetCount();
1449 for (i
= 0; i
< page_count
; ++i
)
1451 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1452 if (page
.window
== wnd
)
1458 wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
)
1460 wxASSERT_MSG(idx
< m_pages
.GetCount(), wxT("Invalid Page index"));
1462 return m_pages
[idx
];
1465 wxAuiNotebookPageArray
& wxAuiTabContainer::GetPages()
1470 size_t wxAuiTabContainer::GetPageCount() const
1472 return m_pages
.GetCount();
1475 void wxAuiTabContainer::AddButton(int id
,
1477 const wxBitmap
& normal_bitmap
,
1478 const wxBitmap
& disabled_bitmap
)
1480 wxAuiTabContainerButton button
;
1482 button
.bitmap
= normal_bitmap
;
1483 button
.dis_bitmap
= disabled_bitmap
;
1484 button
.location
= location
;
1485 button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1487 m_buttons
.Add(button
);
1490 void wxAuiTabContainer::RemoveButton(int id
)
1492 size_t i
, button_count
= m_buttons
.GetCount();
1494 for (i
= 0; i
< button_count
; ++i
)
1496 if (m_buttons
.Item(i
).id
== id
)
1498 m_buttons
.RemoveAt(i
);
1506 size_t wxAuiTabContainer::GetTabOffset() const
1508 return m_tab_offset
;
1511 void wxAuiTabContainer::SetTabOffset(size_t offset
)
1513 m_tab_offset
= offset
;
1519 // Render() renders the tab catalog to the specified DC
1520 // It is a virtual function and can be overridden to
1521 // provide custom drawing capabilities
1522 void wxAuiTabContainer::Render(wxDC
* raw_dc
, wxWindow
* wnd
)
1524 if (!raw_dc
|| !raw_dc
->IsOk())
1530 size_t page_count
= m_pages
.GetCount();
1531 size_t button_count
= m_buttons
.GetCount();
1533 // create off-screen bitmap
1534 bmp
.Create(m_rect
.GetWidth(), m_rect
.GetHeight());
1535 dc
.SelectObject(bmp
);
1540 // find out if size of tabs is larger than can be
1541 // afforded on screen
1542 int total_width
= 0;
1543 int visible_width
= 0;
1544 for (i
= 0; i
< page_count
; ++i
)
1546 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1548 // determine if a close button is on this tab
1549 bool close_button
= false;
1550 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1551 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1553 close_button
= true;
1558 wxSize size
= m_art
->GetTabSize(dc
,
1564 wxAUI_BUTTON_STATE_NORMAL
:
1565 wxAUI_BUTTON_STATE_HIDDEN
,
1568 if (i
+1 < page_count
)
1569 total_width
+= x_extent
;
1571 total_width
+= size
.x
;
1573 if (i
>= m_tab_offset
)
1575 if (i
+1 < page_count
)
1576 visible_width
+= x_extent
;
1578 visible_width
+= size
.x
;
1582 if (total_width
> m_rect
.GetWidth() || m_tab_offset
!= 0)
1584 // show left/right buttons
1585 for (i
= 0; i
< button_count
; ++i
)
1587 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1588 if (button
.id
== wxAUI_BUTTON_LEFT
||
1589 button
.id
== wxAUI_BUTTON_RIGHT
)
1591 button
.cur_state
&= ~wxAUI_BUTTON_STATE_HIDDEN
;
1597 // hide left/right buttons
1598 for (i
= 0; i
< button_count
; ++i
)
1600 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1601 if (button
.id
== wxAUI_BUTTON_LEFT
||
1602 button
.id
== wxAUI_BUTTON_RIGHT
)
1604 button
.cur_state
|= wxAUI_BUTTON_STATE_HIDDEN
;
1609 // determine whether left button should be enabled
1610 for (i
= 0; i
< button_count
; ++i
)
1612 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1613 if (button
.id
== wxAUI_BUTTON_LEFT
)
1615 if (m_tab_offset
== 0)
1616 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
1618 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
1620 if (button
.id
== wxAUI_BUTTON_RIGHT
)
1622 if (visible_width
< m_rect
.GetWidth() - ((int)button_count
*16))
1623 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
1625 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
1632 m_art
->DrawBackground(dc
, wnd
, m_rect
);
1635 int left_buttons_width
= 0;
1636 int right_buttons_width
= 0;
1640 // draw the buttons on the right side
1641 offset
= m_rect
.x
+ m_rect
.width
;
1642 for (i
= 0; i
< button_count
; ++i
)
1644 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
1646 if (button
.location
!= wxRIGHT
)
1648 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
1651 wxRect button_rect
= m_rect
;
1652 button_rect
.SetY(1);
1653 button_rect
.SetWidth(offset
);
1655 m_art
->DrawButton(dc
,
1664 offset
-= button
.rect
.GetWidth();
1665 right_buttons_width
+= button
.rect
.GetWidth();
1672 // draw the buttons on the left side
1674 for (i
= 0; i
< button_count
; ++i
)
1676 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
1678 if (button
.location
!= wxLEFT
)
1680 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
1683 wxRect
button_rect(offset
, 1, 1000, m_rect
.height
);
1685 m_art
->DrawButton(dc
,
1694 offset
+= button
.rect
.GetWidth();
1695 left_buttons_width
+= button
.rect
.GetWidth();
1698 offset
= left_buttons_width
;
1701 offset
+= m_art
->GetIndentSize();
1704 // prepare the tab-close-button array
1705 // make sure tab button entries which aren't used are marked as hidden
1706 for (i
= page_count
; i
< m_tab_close_buttons
.GetCount(); ++i
)
1707 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1709 // make sure there are enough tab button entries to accommodate all tabs
1710 while (m_tab_close_buttons
.GetCount() < page_count
)
1712 wxAuiTabContainerButton tempbtn
;
1713 tempbtn
.id
= wxAUI_BUTTON_CLOSE
;
1714 tempbtn
.location
= wxCENTER
;
1715 tempbtn
.cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1716 m_tab_close_buttons
.Add(tempbtn
);
1720 // buttons before the tab offset must be set to hidden
1721 for (i
= 0; i
< m_tab_offset
; ++i
)
1723 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1729 size_t active
= 999;
1730 int active_offset
= 0;
1734 wxRect rect
= m_rect
;
1736 rect
.height
= m_rect
.height
;
1738 for (i
= m_tab_offset
; i
< page_count
; ++i
)
1740 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1741 wxAuiTabContainerButton
& tab_button
= m_tab_close_buttons
.Item(i
);
1743 // determine if a close button is on this tab
1744 bool close_button
= false;
1745 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1746 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1748 close_button
= true;
1749 if (tab_button
.cur_state
== wxAUI_BUTTON_STATE_HIDDEN
)
1751 tab_button
.id
= wxAUI_BUTTON_CLOSE
;
1752 tab_button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1753 tab_button
.location
= wxCENTER
;
1758 tab_button
.cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1762 rect
.width
= m_rect
.width
- right_buttons_width
- offset
- 2;
1764 if (rect
.width
<= 0)
1773 tab_button
.cur_state
,
1781 active_offset
= offset
;
1789 // make sure to deactivate buttons which are off the screen to the right
1790 for (++i
; i
< m_tab_close_buttons
.GetCount(); ++i
)
1792 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1796 // draw the active tab again so it stands in the foreground
1797 if (active
>= m_tab_offset
&& active
< m_pages
.GetCount())
1799 wxAuiNotebookPage
& page
= m_pages
.Item(active
);
1801 wxAuiTabContainerButton
& tab_button
= m_tab_close_buttons
.Item(active
);
1803 // determine if a close button is on this tab
1804 bool close_button
= false;
1805 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1806 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1808 close_button
= true;
1811 rect
.x
= active_offset
;
1818 tab_button
.cur_state
,
1825 raw_dc
->Blit(m_rect
.x
, m_rect
.y
,
1826 m_rect
.GetWidth(), m_rect
.GetHeight(),
1831 // TabHitTest() tests if a tab was hit, passing the window pointer
1832 // back if that condition was fulfilled. The function returns
1833 // true if a tab was hit, otherwise false
1834 bool wxAuiTabContainer::TabHitTest(int x
, int y
, wxWindow
** hit
) const
1836 if (!m_rect
.Contains(x
,y
))
1839 wxAuiTabContainerButton
* btn
= NULL
;
1840 if (ButtonHitTest(x
, y
, &btn
))
1842 if (m_buttons
.Index(*btn
) != wxNOT_FOUND
)
1846 size_t i
, page_count
= m_pages
.GetCount();
1848 for (i
= m_tab_offset
; i
< page_count
; ++i
)
1850 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1851 if (page
.rect
.Contains(x
,y
))
1862 // ButtonHitTest() tests if a button was hit. The function returns
1863 // true if a button was hit, otherwise false
1864 bool wxAuiTabContainer::ButtonHitTest(int x
, int y
,
1865 wxAuiTabContainerButton
** hit
) const
1867 if (!m_rect
.Contains(x
,y
))
1870 size_t i
, button_count
;
1873 button_count
= m_buttons
.GetCount();
1874 for (i
= 0; i
< button_count
; ++i
)
1876 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1877 if (button
.rect
.Contains(x
,y
) &&
1878 !(button
.cur_state
& (wxAUI_BUTTON_STATE_HIDDEN
|
1879 wxAUI_BUTTON_STATE_DISABLED
)))
1887 button_count
= m_tab_close_buttons
.GetCount();
1888 for (i
= 0; i
< button_count
; ++i
)
1890 wxAuiTabContainerButton
& button
= m_tab_close_buttons
.Item(i
);
1891 if (button
.rect
.Contains(x
,y
) &&
1892 !(button
.cur_state
& (wxAUI_BUTTON_STATE_HIDDEN
|
1893 wxAUI_BUTTON_STATE_DISABLED
)))
1906 // the utility function ShowWnd() is the same as show,
1907 // except it handles wxAuiMDIChildFrame windows as well,
1908 // as the Show() method on this class is "unplugged"
1909 static void ShowWnd(wxWindow
* wnd
, bool show
)
1911 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
1913 wxAuiMDIChildFrame
* cf
= (wxAuiMDIChildFrame
*)wnd
;
1923 // DoShowHide() this function shows the active window, then
1924 // hides all of the other windows (in that order)
1925 void wxAuiTabContainer::DoShowHide()
1927 wxAuiNotebookPageArray
& pages
= GetPages();
1928 size_t i
, page_count
= pages
.GetCount();
1930 // show new active page first
1931 for (i
= 0; i
< page_count
; ++i
)
1933 wxAuiNotebookPage
& page
= pages
.Item(i
);
1936 ShowWnd(page
.window
, true);
1941 // hide all other pages
1942 for (i
= 0; i
< page_count
; ++i
)
1944 wxAuiNotebookPage
& page
= pages
.Item(i
);
1945 ShowWnd(page
.window
, page
.active
);
1954 // -- wxAuiTabCtrl class implementation --
1958 BEGIN_EVENT_TABLE(wxAuiTabCtrl
, wxControl
)
1959 EVT_PAINT(wxAuiTabCtrl::OnPaint
)
1960 EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground
)
1961 EVT_SIZE(wxAuiTabCtrl::OnSize
)
1962 EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown
)
1963 EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp
)
1964 EVT_MOTION(wxAuiTabCtrl::OnMotion
)
1965 EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow
)
1966 EVT_AUINOTEBOOK_BUTTON(-1, wxAuiTabCtrl::OnButton
)
1970 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow
* parent
,
1974 long style
) : wxControl(parent
, id
, pos
, size
, style
)
1976 m_click_pt
= wxDefaultPosition
;
1977 m_is_dragging
= false;
1978 m_hover_button
= NULL
;
1979 m_pressed_button
= NULL
;
1982 wxAuiTabCtrl::~wxAuiTabCtrl()
1986 void wxAuiTabCtrl::OnPaint(wxPaintEvent
&)
1990 dc
.SetFont(GetFont());
1992 if (GetPageCount() > 0)
1996 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent
& WXUNUSED(evt
))
2000 void wxAuiTabCtrl::OnSize(wxSizeEvent
& evt
)
2002 wxSize s
= evt
.GetSize();
2003 wxRect
r(0, 0, s
.GetWidth(), s
.GetHeight());
2007 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent
& evt
)
2010 m_click_pt
= wxDefaultPosition
;
2011 m_is_dragging
= false;
2013 m_pressed_button
= NULL
;
2017 if (TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
2019 int new_selection
= GetIdxFromWindow(wnd
);
2021 if (new_selection
!= GetActivePage())
2023 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2024 e
.SetSelection(new_selection
);
2025 e
.SetOldSelection(GetActivePage());
2026 e
.SetEventObject(this);
2027 GetEventHandler()->ProcessEvent(e
);
2030 m_click_pt
.x
= evt
.m_x
;
2031 m_click_pt
.y
= evt
.m_y
;
2037 m_pressed_button
= m_hover_button
;
2038 m_pressed_button
->cur_state
= wxAUI_BUTTON_STATE_PRESSED
;
2044 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent
& evt
)
2046 if (GetCapture() == this)
2051 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, m_windowId
);
2052 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2053 evt
.SetOldSelection(evt
.GetSelection());
2054 evt
.SetEventObject(this);
2055 GetEventHandler()->ProcessEvent(evt
);
2059 if (m_pressed_button
)
2061 // make sure we're still clicking the button
2062 wxAuiTabContainerButton
* button
= NULL
;
2063 if (!ButtonHitTest(evt
.m_x
, evt
.m_y
, &button
))
2066 if (button
!= m_pressed_button
)
2068 m_pressed_button
= NULL
;
2075 if (!(m_pressed_button
->cur_state
& wxAUI_BUTTON_STATE_DISABLED
))
2077 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, m_windowId
);
2078 evt
.SetInt(m_pressed_button
->id
);
2079 evt
.SetEventObject(this);
2080 GetEventHandler()->ProcessEvent(evt
);
2083 m_pressed_button
= NULL
;
2086 m_click_pt
= wxDefaultPosition
;
2087 m_is_dragging
= false;
2091 void wxAuiTabCtrl::OnMotion(wxMouseEvent
& evt
)
2093 wxPoint pos
= evt
.GetPosition();
2095 // check if the mouse is hovering above a button
2096 wxAuiTabContainerButton
* button
;
2097 if (ButtonHitTest(pos
.x
, pos
.y
, &button
))
2099 if (m_hover_button
&& button
!= m_hover_button
)
2101 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2102 m_hover_button
= NULL
;
2107 if (button
->cur_state
!= wxAUI_BUTTON_STATE_HOVER
)
2109 button
->cur_state
= wxAUI_BUTTON_STATE_HOVER
;
2112 m_hover_button
= button
;
2120 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2121 m_hover_button
= NULL
;
2128 if (!evt
.LeftIsDown() || m_click_pt
== wxDefaultPosition
)
2133 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, m_windowId
);
2134 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2135 evt
.SetOldSelection(evt
.GetSelection());
2136 evt
.SetEventObject(this);
2137 GetEventHandler()->ProcessEvent(evt
);
2142 int drag_x_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_X
);
2143 int drag_y_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_Y
);
2145 if (abs(pos
.x
- m_click_pt
.x
) > drag_x_threshold
||
2146 abs(pos
.y
- m_click_pt
.y
) > drag_y_threshold
)
2148 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, m_windowId
);
2149 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2150 evt
.SetOldSelection(evt
.GetSelection());
2151 evt
.SetEventObject(this);
2152 GetEventHandler()->ProcessEvent(evt
);
2154 m_is_dragging
= true;
2158 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
))
2162 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2163 m_hover_button
= NULL
;
2169 void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent
& event
)
2171 int button
= event
.GetInt();
2173 if (button
== wxAUI_BUTTON_LEFT
|| button
== wxAUI_BUTTON_RIGHT
)
2175 if (button
== wxAUI_BUTTON_LEFT
)
2177 if (GetTabOffset() > 0)
2179 SetTabOffset(GetTabOffset()-1);
2186 SetTabOffset(GetTabOffset()+1);
2191 else if (button
== wxAUI_BUTTON_WINDOWLIST
)
2195 size_t i
, page_count
= m_pages
.GetCount();
2196 for (i
= 0; i
< page_count
; ++i
)
2198 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
2199 as
.Add(page
.caption
);
2202 int idx
= GetArtProvider()->ShowWindowList(this, as
, GetActivePage());
2206 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2207 e
.SetSelection(idx
);
2208 e
.SetOldSelection(GetActivePage());
2209 e
.SetEventObject(this);
2210 GetEventHandler()->ProcessEvent(e
);
2219 // wxTabFrame is an interesting case. It's important that all child pages
2220 // of the multi-notebook control are all actually children of that control
2221 // (and not grandchildren). wxTabFrame facilitates this. There is one
2222 // instance of wxTabFrame for each tab control inside the multi-notebook.
2223 // It's important to know that wxTabFrame is not a real window, but it merely
2224 // used to capture the dimensions/positioning of the internal tab control and
2225 // it's managed page windows
2227 class wxTabFrame
: public wxWindow
2234 m_rect
= wxRect(0,0,200,200);
2235 m_tab_ctrl_height
= 20;
2238 void SetTabCtrlHeight(int h
)
2240 m_tab_ctrl_height
= h
;
2243 void DoSetSize(int x
, int y
,
2244 int width
, int height
,
2245 int WXUNUSED(sizeFlags
= wxSIZE_AUTO
))
2247 m_rect
= wxRect(x
, y
, width
, height
);
2251 void DoGetClientSize(int* x
, int* y
) const
2257 bool Show( bool WXUNUSED(show
= true) ) { return false; }
2264 m_tab_rect
= wxRect(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
);
2265 m_tabs
->SetSize(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
);
2266 m_tabs
->SetRect(wxRect(0, 0, m_rect
.width
, m_tab_ctrl_height
));
2270 wxAuiNotebookPageArray
& pages
= m_tabs
->GetPages();
2271 size_t i
, page_count
= pages
.GetCount();
2273 for (i
= 0; i
< page_count
; ++i
)
2275 wxAuiNotebookPage
& page
= pages
.Item(i
);
2276 page
.window
->SetSize(m_rect
.x
, m_rect
.y
+ m_tab_ctrl_height
,
2277 m_rect
.width
, m_rect
.height
- m_tab_ctrl_height
);
2279 if (page
.window
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
2281 wxAuiMDIChildFrame
* wnd
= (wxAuiMDIChildFrame
*)page
.window
;
2282 wnd
->ApplyMDIChildFrameRect();
2287 void DoGetSize(int* x
, int* y
) const
2290 *x
= m_rect
.GetWidth();
2292 *y
= m_rect
.GetHeight();
2304 wxAuiTabCtrl
* m_tabs
;
2305 int m_tab_ctrl_height
;
2312 // -- wxAuiNotebook class implementation --
2314 BEGIN_EVENT_TABLE(wxAuiNotebook
, wxControl
)
2315 //EVT_ERASE_BACKGROUND(wxAuiNotebook::OnEraseBackground)
2316 EVT_SIZE(wxAuiNotebook::OnSize
)
2317 //EVT_LEFT_DOWN(wxAuiNotebook::OnLeftDown)
2318 EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocus
)
2319 EVT_COMMAND_RANGE(10000, 10100,
2320 wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
,
2321 wxAuiNotebook::OnTabClicked
)
2322 EVT_COMMAND_RANGE(10000, 10100,
2323 wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
,
2324 wxAuiNotebook::OnTabBeginDrag
)
2325 EVT_COMMAND_RANGE(10000, 10100,
2326 wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
,
2327 wxAuiNotebook::OnTabEndDrag
)
2328 EVT_COMMAND_RANGE(10000, 10100,
2329 wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
,
2330 wxAuiNotebook::OnTabDragMotion
)
2331 EVT_COMMAND_RANGE(10000, 10100,
2332 wxEVT_COMMAND_AUINOTEBOOK_BUTTON
,
2333 wxAuiNotebook::OnTabButton
)
2336 wxAuiNotebook::wxAuiNotebook()
2339 m_tab_id_counter
= 10000;
2341 m_tab_ctrl_height
= 20;
2342 m_requested_bmp_size
= wxDefaultSize
;
2343 m_requested_tabctrl_height
= -1;
2346 wxAuiNotebook::wxAuiNotebook(wxWindow
*parent
,
2350 long style
) : wxControl(parent
, id
, pos
, size
, style
)
2353 m_requested_bmp_size
= wxDefaultSize
;
2354 m_requested_tabctrl_height
= -1;
2355 InitNotebook(style
);
2358 bool wxAuiNotebook::Create(wxWindow
* parent
,
2364 if (!wxControl::Create(parent
, id
, pos
, size
, style
))
2367 InitNotebook(style
);
2372 // InitNotebook() contains common initialization
2373 // code called by all constructors
2374 void wxAuiNotebook::InitNotebook(long style
)
2377 m_tab_id_counter
= 10000;
2379 m_flags
= (unsigned int)style
;
2380 m_tab_ctrl_height
= 20;
2382 m_normal_font
= *wxNORMAL_FONT
;
2383 m_selected_font
= *wxNORMAL_FONT
;
2384 m_selected_font
.SetWeight(wxBOLD
);
2386 SetArtProvider(new wxAuiDefaultTabArt
);
2388 m_dummy_wnd
= new wxWindow(this, wxID_ANY
, wxPoint(0,0), wxSize(0,0));
2389 m_dummy_wnd
->SetSize(200, 200);
2390 m_dummy_wnd
->Show(false);
2392 m_mgr
.SetManagedWindow(this);
2393 m_mgr
.SetFlags(wxAUI_MGR_DEFAULT
| (1 << 28) /*wxAUI_MGR_NO_DOCK_SIZE_LIMIT*/);
2395 m_mgr
.AddPane(m_dummy_wnd
,
2396 wxAuiPaneInfo().Name(wxT("dummy")).Bottom().CaptionVisible(false).Show(false));
2401 wxAuiNotebook::~wxAuiNotebook()
2406 void wxAuiNotebook::SetArtProvider(wxAuiTabArt
* art
)
2408 m_tabs
.SetArtProvider(art
);
2410 UpdateTabCtrlHeight();
2413 // SetTabCtrlHeight() is the highest-level override of the
2414 // tab height. A call to this function effectively enforces a
2415 // specified tab ctrl height, overriding all other considerations,
2416 // such as text or bitmap height. It overrides any call to
2417 // SetUniformBitmapSize(). Specifying a height of -1 reverts
2418 // any previous call and returns to the default behavior
2420 void wxAuiNotebook::SetTabCtrlHeight(int height
)
2422 m_requested_tabctrl_height
= height
;
2424 // if window is already initialized, recalculate the tab height
2427 UpdateTabCtrlHeight();
2432 // SetUniformBitmapSize() ensures that all tabs will have
2433 // the same height, even if some tabs don't have bitmaps
2434 // Passing wxDefaultSize to this function will instruct
2435 // the control to use dynamic tab height-- so when a tab
2436 // with a large bitmap is added, the tab ctrl's height will
2437 // automatically increase to accommodate the bitmap
2439 void wxAuiNotebook::SetUniformBitmapSize(const wxSize
& size
)
2441 m_requested_bmp_size
= size
;
2443 // if window is already initialized, recalculate the tab height
2446 UpdateTabCtrlHeight();
2450 // UpdateTabCtrlHeight() does the actual tab resizing. It's meant
2451 // to be used interally
2452 void wxAuiNotebook::UpdateTabCtrlHeight()
2454 // get the tab ctrl height we will use
2455 int height
= CalculateTabCtrlHeight();
2457 // if the tab control height needs to change, update
2458 // all of our tab controls with the new height
2459 if (m_tab_ctrl_height
!= height
)
2461 wxAuiTabArt
* art
= m_tabs
.GetArtProvider();
2463 m_tab_ctrl_height
= height
;
2465 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2466 size_t i
, pane_count
= all_panes
.GetCount();
2467 for (i
= 0; i
< pane_count
; ++i
)
2469 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2470 if (pane
.name
== wxT("dummy"))
2472 wxTabFrame
* tab_frame
= (wxTabFrame
*)pane
.window
;
2473 wxAuiTabCtrl
* tabctrl
= tab_frame
->m_tabs
;
2474 tab_frame
->SetTabCtrlHeight(m_tab_ctrl_height
);
2475 tabctrl
->SetArtProvider(art
->Clone());
2476 tab_frame
->DoSizing();
2481 void wxAuiNotebook::UpdateHintWindowSize()
2483 wxSize size
= CalculateNewSplitSize();
2485 // the placeholder hint window should be set to this size
2486 wxAuiPaneInfo
& info
= m_mgr
.GetPane(wxT("dummy"));
2490 info
.BestSize(size
);
2491 m_dummy_wnd
->SetSize(size
);
2496 // calculates the size of the new split
2497 wxSize
wxAuiNotebook::CalculateNewSplitSize()
2499 // count number of tab controls
2500 int tab_ctrl_count
= 0;
2501 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2502 size_t i
, pane_count
= all_panes
.GetCount();
2503 for (i
= 0; i
< pane_count
; ++i
)
2505 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2506 if (pane
.name
== wxT("dummy"))
2511 wxSize new_split_size
;
2513 // if there is only one tab control, the first split
2514 // should happen around the middle
2515 if (tab_ctrl_count
< 2)
2517 new_split_size
= GetClientSize();
2518 new_split_size
.x
/= 2;
2519 new_split_size
.y
/= 2;
2523 // this is in place of a more complicated calculation
2524 // that needs to be implemented
2525 new_split_size
= wxSize(180,180);
2528 return new_split_size
;
2531 int wxAuiNotebook::CalculateTabCtrlHeight()
2533 // if a fixed tab ctrl height is specified,
2534 // just return that instead of calculating a
2536 if (m_requested_tabctrl_height
!= -1)
2537 return m_requested_tabctrl_height
;
2539 // find out new best tab height
2540 wxAuiTabArt
* art
= m_tabs
.GetArtProvider();
2542 return art
->GetBestTabCtrlSize(this,
2544 m_requested_bmp_size
);
2548 wxAuiTabArt
* wxAuiNotebook::GetArtProvider() const
2550 return m_tabs
.GetArtProvider();
2553 void wxAuiNotebook::SetWindowStyleFlag(long style
)
2555 wxControl::SetWindowStyleFlag(style
);
2557 m_flags
= (unsigned int)style
;
2559 // if the control is already initialized
2560 if (m_mgr
.GetManagedWindow() == (wxWindow
*)this)
2562 // let all of the tab children know about the new style
2564 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2565 size_t i
, pane_count
= all_panes
.GetCount();
2566 for (i
= 0; i
< pane_count
; ++i
)
2568 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2569 if (pane
.name
== wxT("dummy"))
2571 wxTabFrame
* tabframe
= (wxTabFrame
*)pane
.window
;
2572 wxAuiTabCtrl
* tabctrl
= tabframe
->m_tabs
;
2573 tabctrl
->SetFlags(m_flags
);
2574 tabframe
->DoSizing();
2582 bool wxAuiNotebook::AddPage(wxWindow
* page
,
2583 const wxString
& caption
,
2585 const wxBitmap
& bitmap
)
2587 return InsertPage(GetPageCount(), page
, caption
, select
, bitmap
);
2590 bool wxAuiNotebook::InsertPage(size_t page_idx
,
2592 const wxString
& caption
,
2594 const wxBitmap
& bitmap
)
2596 wxAuiNotebookPage info
;
2598 info
.caption
= caption
;
2599 info
.bitmap
= bitmap
;
2600 info
.active
= false;
2602 // if there are currently no tabs, the first added
2603 // tab must be active
2604 if (m_tabs
.GetPageCount() == 0)
2607 m_tabs
.InsertPage(page
, info
, page_idx
);
2609 wxAuiTabCtrl
* active_tabctrl
= GetActiveTabCtrl();
2610 if (page_idx
>= active_tabctrl
->GetPageCount())
2611 active_tabctrl
->AddPage(page
, info
);
2613 active_tabctrl
->InsertPage(page
, info
, page_idx
);
2615 UpdateTabCtrlHeight();
2617 active_tabctrl
->DoShowHide();
2621 int idx
= m_tabs
.GetIdxFromWindow(page
);
2622 wxASSERT_MSG(idx
!= -1, wxT("Invalid Page index returned on wxAuiNotebook::InsertPage()"));
2631 // DeletePage() removes a tab from the multi-notebook,
2632 // and destroys the window as well
2633 bool wxAuiNotebook::DeletePage(size_t page_idx
)
2635 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
2637 if (!RemovePage(page_idx
))
2640 // actually destroy the window now
2641 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
2643 // delete the child frame with pending delete, as is
2644 // customary with frame windows
2645 if (!wxPendingDelete
.Member(wnd
))
2646 wxPendingDelete
.Append(wnd
);
2658 // RemovePage() removes a tab from the multi-notebook,
2659 // but does not destroy the window
2660 bool wxAuiNotebook::RemovePage(size_t page_idx
)
2662 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
2663 wxWindow
* new_active
= NULL
;
2665 // find out which onscreen tab ctrl owns this tab
2668 if (!FindTab(wnd
, &ctrl
, &ctrl_idx
))
2671 // find a new page and set it as active
2672 int new_idx
= ctrl_idx
+1;
2673 if (new_idx
>= (int)ctrl
->GetPageCount())
2674 new_idx
= ctrl_idx
-1;
2676 if (new_idx
>= 0 && new_idx
< (int)ctrl
->GetPageCount())
2678 new_active
= ctrl
->GetWindowFromIdx(new_idx
);
2682 // set the active page to the first page that
2683 // isn't the one being deleted
2684 size_t i
, page_count
= m_tabs
.GetPageCount();
2685 for (i
= 0; i
< page_count
; ++i
)
2687 wxWindow
* w
= m_tabs
.GetWindowFromIdx(i
);
2690 new_active
= m_tabs
.GetWindowFromIdx(i
);
2696 // remove the tab from main catalog
2697 if (!m_tabs
.RemovePage(wnd
))
2700 // remove the tab from the onscreen tab ctrl
2701 ctrl
->RemovePage(wnd
);
2704 RemoveEmptyTabFrames();
2706 // set new active pane
2710 SetSelection(m_tabs
.GetIdxFromWindow(new_active
));
2716 // GetPageIndex() returns the index of the page, or -1 if the
2717 // page could not be located in the notebook
2718 int wxAuiNotebook::GetPageIndex(wxWindow
* page_wnd
) const
2720 return m_tabs
.GetIdxFromWindow(page_wnd
);
2725 // SetPageText() changes the tab caption of the specified page
2726 bool wxAuiNotebook::SetPageText(size_t page_idx
, const wxString
& text
)
2728 if (page_idx
>= m_tabs
.GetPageCount())
2731 // update our own tab catalog
2732 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2733 page_info
.caption
= text
;
2735 // update what's on screen
2738 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
2740 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
2741 info
.caption
= text
;
2750 bool wxAuiNotebook::SetPageBitmap(size_t page_idx
, const wxBitmap
& bitmap
)
2752 if (page_idx
>= m_tabs
.GetPageCount())
2755 // update our own tab catalog
2756 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2757 page_info
.bitmap
= bitmap
;
2759 // tab height might have changed
2760 UpdateTabCtrlHeight();
2762 // update what's on screen
2765 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
2767 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
2768 info
.bitmap
= bitmap
;
2777 // GetSelection() returns the index of the currently active page
2778 int wxAuiNotebook::GetSelection() const
2783 // SetSelection() sets the currently active page
2784 size_t wxAuiNotebook::SetSelection(size_t new_page
)
2786 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(new_page
);
2790 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2791 evt
.SetSelection(new_page
);
2792 evt
.SetOldSelection(m_curpage
);
2793 evt
.SetEventObject(this);
2794 if (!GetEventHandler()->ProcessEvent(evt
) || evt
.IsAllowed())
2796 int old_curpage
= m_curpage
;
2797 m_curpage
= new_page
;
2799 // program allows the page change
2800 evt
.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
);
2801 (void)GetEventHandler()->ProcessEvent(evt
);
2806 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
2808 m_tabs
.SetActivePage(wnd
);
2810 ctrl
->SetActivePage(ctrl_idx
);
2817 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2818 size_t i
, pane_count
= all_panes
.GetCount();
2819 for (i
= 0; i
< pane_count
; ++i
)
2821 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2822 if (pane
.name
== wxT("dummy"))
2824 wxAuiTabCtrl
* tabctrl
= ((wxTabFrame
*)pane
.window
)->m_tabs
;
2825 if (tabctrl
!= ctrl
)
2826 tabctrl
->SetSelectedFont(m_normal_font
);
2828 tabctrl
->SetSelectedFont(m_selected_font
);
2841 // GetPageCount() returns the total number of
2842 // pages managed by the multi-notebook
2843 size_t wxAuiNotebook::GetPageCount() const
2845 return m_tabs
.GetPageCount();
2848 // GetPage() returns the wxWindow pointer of the
2850 wxWindow
* wxAuiNotebook::GetPage(size_t page_idx
) const
2852 wxASSERT(page_idx
< m_tabs
.GetPageCount());
2854 return m_tabs
.GetWindowFromIdx(page_idx
);
2857 // DoSizing() performs all sizing operations in each tab control
2858 void wxAuiNotebook::DoSizing()
2860 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2861 size_t i
, pane_count
= all_panes
.GetCount();
2862 for (i
= 0; i
< pane_count
; ++i
)
2864 if (all_panes
.Item(i
).name
== wxT("dummy"))
2867 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2868 tabframe
->DoSizing();
2872 // GetActiveTabCtrl() returns the active tab control. It is
2873 // called to determine which control gets new windows being added
2874 wxAuiTabCtrl
* wxAuiNotebook::GetActiveTabCtrl()
2876 if (m_curpage
>= 0 && m_curpage
< (int)m_tabs
.GetPageCount())
2881 // find the tab ctrl with the current page
2882 if (FindTab(m_tabs
.GetPage(m_curpage
).window
,
2889 // no current page, just find the first tab ctrl
2890 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2891 size_t i
, pane_count
= all_panes
.GetCount();
2892 for (i
= 0; i
< pane_count
; ++i
)
2894 if (all_panes
.Item(i
).name
== wxT("dummy"))
2897 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2898 return tabframe
->m_tabs
;
2901 // If there is no tabframe at all, create one
2902 wxTabFrame
* tabframe
= new wxTabFrame
;
2903 tabframe
->SetTabCtrlHeight(m_tab_ctrl_height
);
2904 tabframe
->m_tabs
= new wxAuiTabCtrl(this,
2909 tabframe
->m_tabs
->SetFlags(m_flags
);
2910 tabframe
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
2911 m_mgr
.AddPane(tabframe
,
2912 wxAuiPaneInfo().Center().CaptionVisible(false));
2916 return tabframe
->m_tabs
;
2919 // FindTab() finds the tab control that currently contains the window as well
2920 // as the index of the window in the tab control. It returns true if the
2921 // window was found, otherwise false.
2922 bool wxAuiNotebook::FindTab(wxWindow
* page
, wxAuiTabCtrl
** ctrl
, int* idx
)
2924 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2925 size_t i
, pane_count
= all_panes
.GetCount();
2926 for (i
= 0; i
< pane_count
; ++i
)
2928 if (all_panes
.Item(i
).name
== wxT("dummy"))
2931 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2933 int page_idx
= tabframe
->m_tabs
->GetIdxFromWindow(page
);
2936 *ctrl
= tabframe
->m_tabs
;
2946 void wxAuiNotebook::OnEraseBackground(wxEraseEvent
&)
2950 void wxAuiNotebook::OnSize(wxSizeEvent
& evt
)
2952 UpdateHintWindowSize();
2957 void wxAuiNotebook::OnTabClicked(wxCommandEvent
& command_evt
)
2959 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
2961 wxAuiTabCtrl
* ctrl
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2962 wxASSERT(ctrl
!= NULL
);
2964 wxWindow
* wnd
= ctrl
->GetWindowFromIdx(evt
.GetSelection());
2965 wxASSERT(wnd
!= NULL
);
2967 int idx
= m_tabs
.GetIdxFromWindow(wnd
);
2968 wxASSERT(idx
!= -1);
2973 void wxAuiNotebook::OnTabBeginDrag(wxCommandEvent
&)
2978 void wxAuiNotebook::OnTabDragMotion(wxCommandEvent
& evt
)
2980 wxPoint screen_pt
= ::wxGetMousePosition();
2981 wxPoint client_pt
= ScreenToClient(screen_pt
);
2984 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2985 wxAuiTabCtrl
* dest_tabs
= GetTabCtrlFromPoint(client_pt
);
2987 if (dest_tabs
== src_tabs
)
2991 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
2994 // always hide the hint for inner-tabctrl drag
2997 // if tab moving is not allowed, leave
2998 if (!(m_flags
& wxAUI_NB_TAB_MOVE
))
3003 wxPoint pt
= dest_tabs
->ScreenToClient(screen_pt
);
3004 wxWindow
* dest_location_tab
;
3006 // this is an inner-tab drag/reposition
3007 if (dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &dest_location_tab
))
3009 int src_idx
= evt
.GetSelection();
3010 int dest_idx
= dest_tabs
->GetIdxFromWindow(dest_location_tab
);
3012 // prevent jumpy drag
3013 if ((src_idx
== dest_idx
) || dest_idx
== -1 ||
3014 (src_idx
> dest_idx
&& m_last_drag_x
<= pt
.x
) ||
3015 (src_idx
< dest_idx
&& m_last_drag_x
>= pt
.x
))
3017 m_last_drag_x
= pt
.x
;
3022 wxWindow
* src_tab
= dest_tabs
->GetWindowFromIdx(src_idx
);
3023 dest_tabs
->MovePage(src_tab
, dest_idx
);
3024 dest_tabs
->SetActivePage((size_t)dest_idx
);
3025 dest_tabs
->DoShowHide();
3026 dest_tabs
->Refresh();
3027 m_last_drag_x
= pt
.x
;
3035 // if external drag is allowed, check if the tab is being dragged
3036 // over a different wxAuiNotebook control
3037 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
3039 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(screen_pt
);
3041 // if we aren't over any window, stop here
3045 // make sure we are not over the hint window
3046 if (!tab_ctrl
->IsKindOf(CLASSINFO(wxFrame
)))
3050 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
3052 tab_ctrl
= tab_ctrl
->GetParent();
3057 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
3061 wxRect hint_rect
= tab_ctrl
->GetClientRect();
3062 tab_ctrl
->ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
3063 m_mgr
.ShowHint(hint_rect
);
3072 // we are either over a hint window, or not over a tab
3073 // window, and there is no where to drag to, so exit
3080 // if there are less than two panes, split can't happen, so leave
3081 if (m_tabs
.GetPageCount() < 2)
3084 // if tab moving is not allowed, leave
3085 if (!(m_flags
& wxAUI_NB_TAB_SPLIT
))
3091 src_tabs
->SetCursor(wxCursor(wxCURSOR_SIZING
));
3097 wxRect hint_rect
= dest_tabs
->GetRect();
3098 ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
3099 m_mgr
.ShowHint(hint_rect
);
3103 m_mgr
.DrawHintRect(m_dummy_wnd
, client_pt
, zero
);
3109 void wxAuiNotebook::OnTabEndDrag(wxCommandEvent
& command_evt
)
3111 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
3116 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3117 wxAuiTabCtrl
* dest_tabs
= NULL
;
3120 // set cursor back to an arrow
3121 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
3124 // get the mouse position, which will be used to determine the drop point
3125 wxPoint mouse_screen_pt
= ::wxGetMousePosition();
3126 wxPoint mouse_client_pt
= ScreenToClient(mouse_screen_pt
);
3130 // check for an external move
3131 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
3133 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(mouse_screen_pt
);
3137 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
3139 tab_ctrl
= tab_ctrl
->GetParent();
3144 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
3148 // find out from the destination control
3149 // if it's ok to drop this tab here
3150 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
, m_windowId
);
3151 e
.SetSelection(evt
.GetSelection());
3152 e
.SetOldSelection(evt
.GetSelection());
3153 e
.SetEventObject(this);
3154 e
.SetDragSource(this);
3155 e
.Veto(); // dropping must be explicitly approved by control owner
3157 nb
->GetEventHandler()->ProcessEvent(e
);
3161 // no answer or negative answer
3167 int src_idx
= evt
.GetSelection();
3168 wxWindow
* src_page
= src_tabs
->GetWindowFromIdx(src_idx
);
3170 // get main index of the page
3171 int main_idx
= m_tabs
.GetIdxFromWindow(src_page
);
3173 // make a copy of the page info
3174 wxAuiNotebookPage page_info
= m_tabs
.GetPage((size_t)main_idx
);
3176 // remove the page from the source notebook
3177 RemovePage(main_idx
);
3179 // reparent the page
3180 src_page
->Reparent(nb
);
3183 // found out the insert idx
3184 wxAuiTabCtrl
* dest_tabs
= (wxAuiTabCtrl
*)tab_ctrl
;
3185 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
3187 wxWindow
* target
= NULL
;
3188 int insert_idx
= -1;
3189 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
3192 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
3196 // add the page to the new notebook
3197 if (insert_idx
== -1)
3198 insert_idx
= dest_tabs
->GetPageCount();
3199 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
3200 nb
->m_tabs
.AddPage(page_info
.window
, page_info
);
3203 dest_tabs
->DoShowHide();
3204 dest_tabs
->Refresh();
3206 // set the selection in the destination tab control
3207 nb
->SetSelection(nb
->m_tabs
.GetIdxFromWindow(page_info
.window
));
3217 // only perform a tab split if it's allowed
3218 if ((m_flags
& wxAUI_NB_TAB_SPLIT
) && m_tabs
.GetPageCount() >= 2)
3220 // If the pointer is in an existing tab frame, do a tab insert
3221 wxWindow
* hit_wnd
= ::wxFindWindowAtPoint(mouse_screen_pt
);
3222 wxTabFrame
* tab_frame
= (wxTabFrame
*)GetTabFrameFromTabCtrl(hit_wnd
);
3223 int insert_idx
= -1;
3226 dest_tabs
= tab_frame
->m_tabs
;
3228 if (dest_tabs
== src_tabs
)
3232 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
3233 wxWindow
* target
= NULL
;
3234 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
3237 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
3243 wxRect rect
= m_mgr
.CalculateHintRect(m_dummy_wnd
,
3248 // there is no suitable drop location here, exit out
3252 // If there is no tabframe at all, create one
3253 wxTabFrame
* new_tabs
= new wxTabFrame
;
3254 new_tabs
->m_rect
= wxRect(wxPoint(0,0), CalculateNewSplitSize());
3255 new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
);
3256 new_tabs
->m_tabs
= new wxAuiTabCtrl(this,
3261 new_tabs
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
3262 new_tabs
->m_tabs
->SetFlags(m_flags
);
3264 m_mgr
.AddPane(new_tabs
,
3265 wxAuiPaneInfo().Bottom().CaptionVisible(false),
3268 dest_tabs
= new_tabs
->m_tabs
;
3273 // remove the page from the source tabs
3274 wxAuiNotebookPage page_info
= src_tabs
->GetPage(evt
.GetSelection());
3275 page_info
.active
= false;
3276 src_tabs
->RemovePage(page_info
.window
);
3277 if (src_tabs
->GetPageCount() > 0)
3279 src_tabs
->SetActivePage((size_t)0);
3280 src_tabs
->DoShowHide();
3281 src_tabs
->Refresh();
3286 // add the page to the destination tabs
3287 if (insert_idx
== -1)
3288 insert_idx
= dest_tabs
->GetPageCount();
3289 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
3291 if (src_tabs
->GetPageCount() == 0)
3293 RemoveEmptyTabFrames();
3297 dest_tabs
->DoShowHide();
3298 dest_tabs
->Refresh();
3300 SetSelection(m_tabs
.GetIdxFromWindow(page_info
.window
));
3302 UpdateHintWindowSize();
3308 wxAuiTabCtrl
* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint
& pt
)
3310 // if we've just removed the last tab from the source
3311 // tab set, the remove the tab control completely
3312 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
3313 size_t i
, pane_count
= all_panes
.GetCount();
3314 for (i
= 0; i
< pane_count
; ++i
)
3316 if (all_panes
.Item(i
).name
== wxT("dummy"))
3319 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3320 if (tabframe
->m_tab_rect
.Contains(pt
))
3321 return tabframe
->m_tabs
;
3327 wxWindow
* wxAuiNotebook::GetTabFrameFromTabCtrl(wxWindow
* tab_ctrl
)
3329 // if we've just removed the last tab from the source
3330 // tab set, the remove the tab control completely
3331 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
3332 size_t i
, pane_count
= all_panes
.GetCount();
3333 for (i
= 0; i
< pane_count
; ++i
)
3335 if (all_panes
.Item(i
).name
== wxT("dummy"))
3338 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3339 if (tabframe
->m_tabs
== tab_ctrl
)
3348 void wxAuiNotebook::RemoveEmptyTabFrames()
3350 // if we've just removed the last tab from the source
3351 // tab set, the remove the tab control completely
3352 wxAuiPaneInfoArray all_panes
= m_mgr
.GetAllPanes();
3353 size_t i
, pane_count
= all_panes
.GetCount();
3354 for (i
= 0; i
< pane_count
; ++i
)
3356 if (all_panes
.Item(i
).name
== wxT("dummy"))
3359 wxTabFrame
* tab_frame
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3360 if (tab_frame
->m_tabs
->GetPageCount() == 0)
3362 m_mgr
.DetachPane(tab_frame
);
3364 // use pending delete because sometimes during
3365 // window closing, refreshs are pending
3366 if (!wxPendingDelete
.Member(tab_frame
->m_tabs
))
3367 wxPendingDelete
.Append(tab_frame
->m_tabs
);
3368 //tab_frame->m_tabs->Destroy();
3375 // check to see if there is still a center pane;
3376 // if there isn't, make a frame the center pane
3377 wxAuiPaneInfoArray panes
= m_mgr
.GetAllPanes();
3378 pane_count
= panes
.GetCount();
3379 wxWindow
* first_good
= NULL
;
3380 bool center_found
= false;
3381 for (i
= 0; i
< pane_count
; ++i
)
3383 if (panes
.Item(i
).name
== wxT("dummy"))
3385 if (panes
.Item(i
).dock_direction
== wxAUI_DOCK_CENTRE
)
3386 center_found
= true;
3388 first_good
= panes
.Item(i
).window
;
3391 if (!center_found
&& first_good
)
3393 m_mgr
.GetPane(first_good
).Centre();
3399 void wxAuiNotebook::OnChildFocus(wxChildFocusEvent
& evt
)
3401 int idx
= m_tabs
.GetIdxFromWindow(evt
.GetWindow());
3402 if (idx
!= -1 && idx
!= m_curpage
)
3409 void wxAuiNotebook::OnTabButton(wxCommandEvent
& command_evt
)
3411 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
3412 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3414 int button_id
= evt
.GetInt();
3416 if (button_id
== wxAUI_BUTTON_CLOSE
)
3418 int selection
= tabs
->GetActivePage();
3420 if (selection
!= -1)
3422 wxWindow
* close_wnd
= tabs
->GetWindowFromIdx(selection
);
3425 // ask owner if it's ok to close the tab
3426 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
, m_windowId
);
3427 e
.SetSelection(m_tabs
.GetIdxFromWindow(close_wnd
));
3428 e
.SetOldSelection(evt
.GetSelection());
3429 e
.SetEventObject(this);
3430 GetEventHandler()->ProcessEvent(e
);
3435 if (close_wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
3441 int main_idx
= m_tabs
.GetIdxFromWindow(close_wnd
);
3442 DeletePage(main_idx
);