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 // This functions are here for this proof of concept
61 // and will be factored out later. See dockart.cpp
62 static wxColor
StepColour(const wxColor
& c
, int percent
)
64 int r
= c
.Red(), g
= c
.Green(), b
= c
.Blue();
65 return wxColour((unsigned char)wxMin((r
*percent
)/100,255),
66 (unsigned char)wxMin((g
*percent
)/100,255),
67 (unsigned char)wxMin((b
*percent
)/100,255));
70 // This functions are here for this proof of concept
71 // and will be factored out later. See dockart.cpp
72 static wxBitmap
BitmapFromBits(const unsigned char bits
[], int w
, int h
,
73 const wxColour
& color
)
75 wxImage img
= wxBitmap((const char*)bits
, w
, h
).ConvertToImage();
76 img
.Replace(0,0,0,123,123,123);
77 img
.Replace(255,255,255,color
.Red(),color
.Green(),color
.Blue());
78 img
.SetMaskColour(123,123,123);
82 static void DrawButtons(wxDC
& dc
,
85 const wxColour
& bkcolour
,
90 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
96 if (button_state
== wxAUI_BUTTON_STATE_HOVER
||
97 button_state
== wxAUI_BUTTON_STATE_PRESSED
)
99 dc
.SetBrush(wxBrush(StepColour(bkcolour
, 120)));
100 dc
.SetPen(wxPen(StepColour(bkcolour
, 70)));
102 // draw the background behind the button
103 dc
.DrawRectangle(rect
.x
, rect
.y
, 15, 15);
106 // draw the button itself
107 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
110 static void IndentPressedBitmap(wxRect
* rect
, int button_state
)
112 if (button_state
== wxAUI_BUTTON_STATE_PRESSED
)
119 // chops the text so that it fits within |max_size| pixels.
120 // Also adds an elipsis if necessary
122 static wxString
ChopText(wxDC
& dc
, const wxString
& text
, int max_size
)
126 // first check if the text fits with no problems
127 dc
.GetTextExtent(text
, &x
, &y
);
131 size_t i
, len
= text
.Length();
132 size_t last_good_length
= 0;
133 for (i
= 0; i
< len
; ++i
)
135 wxString s
= text
.Left(i
);
138 dc
.GetTextExtent(s
, &x
, &y
);
142 last_good_length
= i
;
145 wxString ret
= text
.Left(last_good_length
);
151 // -- GUI helper classes and functions --
153 class wxAuiCommandCapture
: public wxEvtHandler
157 wxAuiCommandCapture() { m_last_id
= 0; }
158 int GetCommandId() const { return m_last_id
; }
160 bool ProcessEvent(wxEvent
& evt
)
162 if (evt
.GetEventType() == wxEVT_COMMAND_MENU_SELECTED
)
164 m_last_id
= evt
.GetId();
168 if (GetNextHandler())
169 return GetNextHandler()->ProcessEvent(evt
);
181 #if defined( __WXMAC__ )
182 static unsigned char close_bits
[]={
183 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
184 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
185 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
186 #elif defined( __WXGTK__)
187 static unsigned char close_bits
[]={
188 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
189 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
190 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
192 static unsigned char close_bits
[]={
193 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xf3, 0xcf, 0xf9,
194 0x9f, 0xfc, 0x3f, 0xfe, 0x3f, 0xfe, 0x9f, 0xfc, 0xcf, 0xf9, 0xe7, 0xf3,
195 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
198 static unsigned char left_bits
[] = {
199 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
200 0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
201 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
203 static unsigned char right_bits
[] = {
204 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
205 0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
206 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
208 static unsigned char list_bits
[] = {
209 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
210 0x0f, 0xf8, 0xff, 0xff, 0x0f, 0xf8, 0x1f, 0xfc, 0x3f, 0xfe, 0x7f, 0xff,
211 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
218 // -- wxAuiDefaultTabArt class implementation --
220 wxAuiDefaultTabArt::wxAuiDefaultTabArt()
222 m_normal_font
= *wxNORMAL_FONT
;
223 m_selected_font
= *wxNORMAL_FONT
;
224 m_selected_font
.SetWeight(wxBOLD
);
225 m_measuring_font
= m_selected_font
;
227 m_fixed_tab_width
= 100;
228 m_tab_ctrl_height
= 0;
231 wxBrush toolbarbrush
;
232 toolbarbrush
.MacSetTheme( kThemeBrushToolbarBackground
);
233 wxColor base_colour
= toolbarbrush
.GetColour();
235 wxColor base_colour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
238 m_base_colour
= base_colour
;
239 wxColor darker2_colour
= StepColour(base_colour
, 70);
241 m_border_pen
= wxPen(darker2_colour
);
242 m_base_colour_pen
= wxPen(m_base_colour
);
243 m_base_colour_brush
= wxBrush(m_base_colour
);
245 m_active_close_bmp
= BitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
246 m_disabled_close_bmp
= BitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
248 m_active_left_bmp
= BitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
249 m_disabled_left_bmp
= BitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
251 m_active_right_bmp
= BitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
252 m_disabled_right_bmp
= BitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
254 m_active_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
255 m_disabled_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
260 wxAuiDefaultTabArt::~wxAuiDefaultTabArt()
264 wxAuiTabArt
* wxAuiDefaultTabArt::Clone()
266 return static_cast<wxAuiTabArt
*>(new wxAuiDefaultTabArt
);
269 void wxAuiDefaultTabArt::SetFlags(unsigned int flags
)
274 void wxAuiDefaultTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
277 m_fixed_tab_width
= 100;
279 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
281 if (m_flags
& wxAUI_NB_CLOSE_BUTTON
)
282 tot_width
-= m_active_close_bmp
.GetWidth();
283 if (m_flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
284 tot_width
-= m_active_windowlist_bmp
.GetWidth();
288 m_fixed_tab_width
= tot_width
/(int)tab_count
;
292 if (m_fixed_tab_width
< 100)
293 m_fixed_tab_width
= 100;
295 if (m_fixed_tab_width
> tot_width
/2)
296 m_fixed_tab_width
= tot_width
/2;
298 if (m_fixed_tab_width
> 220)
299 m_fixed_tab_width
= 220;
301 m_tab_ctrl_height
= tab_ctrl_size
.y
;
305 void wxAuiDefaultTabArt::DrawBackground(wxDC
& dc
,
306 wxWindow
* WXUNUSED(wnd
),
310 wxRect
r(rect
.x
, rect
.y
, rect
.width
+2, rect
.height
-3);
311 wxColor start_colour
= StepColour(m_base_colour
, 90);
312 wxColor end_colour
= StepColour(m_base_colour
, 110);
313 dc
.GradientFillLinear(r
, start_colour
, end_colour
, wxSOUTH
);
316 int y
= rect
.GetHeight();
317 int w
= rect
.GetWidth();
318 dc
.SetPen(m_border_pen
);
319 dc
.DrawLine(0, y
-4, w
, y
-4);
320 dc
.DrawLine(0, y
-1, w
, y
-1);
321 dc
.SetPen(wxPen(start_colour
));
322 dc
.DrawLine(0, y
-3, w
, y
-3);
323 dc
.DrawLine(0, y
-2, w
, y
-2);
327 // DrawTab() draws an individual tab.
330 // in_rect - rectangle the tab should be confined to
331 // caption - tab's caption
332 // active - whether or not the tab is active
333 // out_rect - actual output rectangle
334 // x_extent - the advance x; where the next tab should start
336 void wxAuiDefaultTabArt::DrawTab(wxDC
& dc
,
338 const wxRect
& in_rect
,
339 const wxString
& caption_text
,
340 const wxBitmap
& bitmap
,
342 int close_button_state
,
343 wxRect
* out_tab_rect
,
344 wxRect
* out_button_rect
,
347 wxCoord normal_textx
, normal_texty
;
348 wxCoord selected_textx
, selected_texty
;
349 wxCoord textx
, texty
;
351 // if the caption is empty, measure some temporary text
352 wxString caption
= caption_text
;
353 if (caption_text
.empty())
356 dc
.SetFont(m_selected_font
);
357 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
359 dc
.SetFont(m_normal_font
);
360 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
362 // figure out the size of the tab
363 wxSize tab_size
= GetTabSize(dc
,
371 wxCoord tab_height
= m_tab_ctrl_height
- 3;
372 wxCoord tab_width
= tab_size
.x
;
373 wxCoord tab_x
= in_rect
.x
;
374 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
377 caption
= caption_text
;
380 // select pen, brush and font for the tab to be drawn
384 dc
.SetFont(m_selected_font
);
385 textx
= selected_textx
;
386 texty
= selected_texty
;
390 dc
.SetFont(m_normal_font
);
391 textx
= normal_textx
;
392 texty
= normal_texty
;
396 // create points that will make the tab outline
398 int clip_width
= tab_width
;
399 if (tab_x
+ clip_width
> in_rect
.x
+ in_rect
.width
)
400 clip_width
= (in_rect
.x
+ in_rect
.width
) - tab_x
;
402 wxPoint clip_points
[6];
403 clip_points
[0] = wxPoint(tab_x
, tab_y
+tab_height
-3);
404 clip_points
[1] = wxPoint(tab_x
, tab_y
+2);
405 clip_points
[2] = wxPoint(tab_x
+2, tab_y
);
406 clip_points
[3] = wxPoint(tab_x
+clip_width
-1, tab_y
);
407 clip_points
[4] = wxPoint(tab_x
+clip_width
+1, tab_y
+2);
408 clip_points
[5] = wxPoint(tab_x
+clip_width
+1, tab_y
+tab_height
-3);
410 // FIXME: these ports don't provide wxRegion ctor from array of points
411 #if !defined(__WXDFB__)
412 // set the clipping region for the tab --
413 wxRegion
clipping_region(WXSIZEOF(clip_points
), clip_points
);
414 dc
.SetClippingRegion(clipping_region
);
417 wxPoint border_points
[6];
418 border_points
[0] = wxPoint(tab_x
, tab_y
+tab_height
-4);
419 border_points
[1] = wxPoint(tab_x
, tab_y
+2);
420 border_points
[2] = wxPoint(tab_x
+2, tab_y
);
421 border_points
[3] = wxPoint(tab_x
+tab_width
-2, tab_y
);
422 border_points
[4] = wxPoint(tab_x
+tab_width
, tab_y
+2);
423 border_points
[5] = wxPoint(tab_x
+tab_width
, tab_y
+tab_height
-4);
426 int drawn_tab_yoff
= border_points
[1].y
;
427 int drawn_tab_height
= border_points
[0].y
- border_points
[1].y
;
434 // draw base background color
435 wxRect
r(tab_x
, tab_y
, tab_width
, tab_height
);
436 dc
.SetPen(m_base_colour_pen
);
437 dc
.SetBrush(m_base_colour_brush
);
438 dc
.DrawRectangle(r
.x
, r
.y
, r
.width
, r
.height
);
440 // this white helps fill out the gradient at the top of the tab
441 dc
.SetPen(*wxWHITE_PEN
);
442 dc
.SetBrush(*wxWHITE_BRUSH
);
443 dc
.DrawRectangle(r
.x
+2, r
.y
+2, r
.width
-3, r
.height
);
445 // these two points help the rounded corners appear more antialiased
446 dc
.SetPen(m_base_colour_pen
);
447 dc
.DrawPoint(r
.x
+2, r
.y
+2);
448 dc
.DrawPoint(r
.x
+r
.width
-2, r
.y
+2);
450 // set rectangle down a bit for gradient drawing
451 r
.SetHeight(r
.GetHeight()/2);
456 // draw gradient background
457 wxColor start_color
= StepColour(m_base_colour
, 95);
458 wxColor end_color
= *wxWHITE
;
459 dc
.GradientFillLinear(r
, start_color
, end_color
, wxNORTH
);
465 wxRect
r(tab_x
, tab_y
+1, tab_width
, tab_height
-3);
467 // draw base background color for inactive tabs
468 dc
.SetPen(m_base_colour_pen
);
469 dc
.SetBrush(m_base_colour_brush
);
470 dc
.DrawRectangle(r
.x
, r
.y
, r
.width
, r
.height
);
472 // start the gradent up a bit and leave the inside border inset
473 // by a pixel for a 3D look. Only the top half of the inactive
474 // tab will have a slight gradient
479 // -- draw bottom gradient fill for glossy look
480 wxColor top_color
= m_base_colour
;
481 wxColor bottom_color
= StepColour(top_color
, 106);
482 dc
.GradientFillLinear(r
, bottom_color
, top_color
, wxNORTH
);
486 dc
.SetPen(m_border_pen
);
487 dc
.SetBrush(*wxTRANSPARENT_BRUSH
);
488 dc
.DrawPolygon(WXSIZEOF(border_points
), border_points
);
490 // there are two horizontal grey lines at the bottom of the tab control,
491 // this gets rid of the top one of those lines in the tab control
494 wxColor start_color
= StepColour(m_base_colour
, 93);
495 dc
.SetPen(wxPen(start_color
));
496 dc
.DrawLine(border_points
[0].x
,
498 border_points
[5].x
+1,
503 int text_offset
= tab_x
+ 8;
504 int close_button_width
= 0;
505 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
507 close_button_width
= m_active_close_bmp
.GetWidth();
513 int bitmap_offset
= tab_x
+ 8;
516 dc
.DrawBitmap(bitmap
,
518 drawn_tab_yoff
+ (drawn_tab_height
/2) - (bitmap
.GetHeight()/2) + 1,
521 text_offset
= bitmap_offset
+ bitmap
.GetWidth();
522 text_offset
+= 3; // bitmap padding
526 text_offset
= tab_x
+ 8;
530 wxString draw_text
= ChopText(dc
,
532 tab_width
- (text_offset
-tab_x
) - close_button_width
);
535 dc
.DrawText(draw_text
,
537 drawn_tab_yoff
+ (drawn_tab_height
)/2 - (texty
/2) - 1);
542 // draw close button if necessary
543 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
545 wxBitmap bmp
= m_disabled_close_bmp
;
547 if (close_button_state
== wxAUI_BUTTON_STATE_HOVER
||
548 close_button_state
== wxAUI_BUTTON_STATE_PRESSED
)
550 bmp
= m_active_close_bmp
;
553 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
554 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2),
557 IndentPressedBitmap(&rect
, close_button_state
);
558 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
560 *out_button_rect
= rect
;
563 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
565 dc
.DestroyClippingRegion();
568 int wxAuiDefaultTabArt::GetIndentSize()
573 wxSize
wxAuiDefaultTabArt::GetTabSize(wxDC
& dc
,
574 wxWindow
* WXUNUSED(wnd
),
575 const wxString
& caption
,
576 const wxBitmap
& bitmap
,
577 bool WXUNUSED(active
),
578 int close_button_state
,
581 wxCoord measured_textx
, measured_texty
, tmp
;
583 dc
.SetFont(m_measuring_font
);
584 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
586 dc
.GetTextExtent(wxT("ABCDEFXj"), &tmp
, &measured_texty
);
588 // add padding around the text
589 wxCoord tab_width
= measured_textx
;
590 wxCoord tab_height
= measured_texty
;
592 // if the close button is showing, add space for it
593 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
594 tab_width
+= m_active_close_bmp
.GetWidth() + 3;
596 // if there's a bitmap, add space for it
599 tab_width
+= bitmap
.GetWidth();
600 tab_width
+= 3; // right side bitmap padding
601 tab_height
= wxMax(tab_height
, bitmap
.GetHeight());
608 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
610 tab_width
= m_fixed_tab_width
;
613 *x_extent
= tab_width
;
615 return wxSize(tab_width
, tab_height
);
619 void wxAuiDefaultTabArt::DrawButton(wxDC
& dc
,
620 wxWindow
* WXUNUSED(wnd
),
621 const wxRect
& in_rect
,
625 const wxBitmap
& bitmap_override
,
631 if (bitmap_override
.IsOk())
633 bmp
= bitmap_override
;
639 case wxAUI_BUTTON_CLOSE
:
640 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
641 bmp
= m_disabled_close_bmp
;
643 bmp
= m_active_close_bmp
;
645 case wxAUI_BUTTON_LEFT
:
646 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
647 bmp
= m_disabled_left_bmp
;
649 bmp
= m_active_left_bmp
;
651 case wxAUI_BUTTON_RIGHT
:
652 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
653 bmp
= m_disabled_right_bmp
;
655 bmp
= m_active_right_bmp
;
657 case wxAUI_BUTTON_WINDOWLIST
:
658 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
659 bmp
= m_disabled_windowlist_bmp
;
661 bmp
= m_active_windowlist_bmp
;
671 if (orientation
== wxLEFT
)
673 rect
.SetX(in_rect
.x
);
674 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
675 rect
.SetWidth(bmp
.GetWidth());
676 rect
.SetHeight(bmp
.GetHeight());
680 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
681 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
682 bmp
.GetWidth(), bmp
.GetHeight());
685 IndentPressedBitmap(&rect
, button_state
);
686 dc
.DrawBitmap(bmp
, rect
.x
, rect
.y
, true);
692 int wxAuiDefaultTabArt::ShowWindowList(wxWindow
* wnd
,
693 const wxArrayString
& items
,
698 size_t i
, count
= items
.GetCount();
699 for (i
= 0; i
< count
; ++i
)
701 menuPopup
.AppendCheckItem(1000+i
, items
.Item(i
));
704 if (active_idx
!= -1)
706 menuPopup
.Check(1000+active_idx
, true);
709 // find out where to put the popup menu of window
710 // items. Subtract 100 for now to center the menu
711 // a bit, until a better mechanism can be implemented
712 wxPoint pt
= ::wxGetMousePosition();
713 pt
= wnd
->ScreenToClient(pt
);
719 // find out the screen coordinate at the bottom of the tab ctrl
720 wxRect cli_rect
= wnd
->GetClientRect();
721 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
723 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
724 wnd
->PushEventHandler(cc
);
725 wnd
->PopupMenu(&menuPopup
, pt
);
726 int command
= cc
->GetCommandId();
727 wnd
->PopEventHandler(true);
735 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
736 wxAuiNotebookPageArray
& pages
)
739 dc
.SetFont(m_measuring_font
);
742 size_t i
, page_count
= pages
.GetCount();
743 for (i
= 0; i
< page_count
; ++i
)
745 wxAuiNotebookPage
& page
= pages
.Item(i
);
747 // we don't use the caption text because we don't
748 // want tab heights to be different in the case
749 // of a very short piece of text on one tab and a very
750 // tall piece of text on another tab
752 wxSize s
= GetTabSize(dc
,
757 wxAUI_BUTTON_STATE_HIDDEN
,
759 max_y
= wxMax(max_y
, s
.y
);
765 void wxAuiDefaultTabArt::SetNormalFont(const wxFont
& font
)
767 m_normal_font
= font
;
770 void wxAuiDefaultTabArt::SetSelectedFont(const wxFont
& font
)
772 m_selected_font
= font
;
775 void wxAuiDefaultTabArt::SetMeasuringFont(const wxFont
& font
)
777 m_measuring_font
= font
;
781 // -- wxAuiSimpleTabArt class implementation --
783 wxAuiSimpleTabArt::wxAuiSimpleTabArt()
785 m_normal_font
= *wxNORMAL_FONT
;
786 m_selected_font
= *wxNORMAL_FONT
;
787 m_selected_font
.SetWeight(wxBOLD
);
788 m_measuring_font
= m_selected_font
;
791 m_fixed_tab_width
= 100;
793 wxColour base_colour
= wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE
);
795 wxColour background_colour
= StepColour(base_colour
, 95);
796 wxColour normaltab_colour
= base_colour
;
797 wxColour selectedtab_colour
= *wxWHITE
;
799 m_bkbrush
= wxBrush(background_colour
);
800 m_normal_bkbrush
= wxBrush(normaltab_colour
);
801 m_normal_bkpen
= wxPen(normaltab_colour
);
802 m_selected_bkbrush
= wxBrush(selectedtab_colour
);
803 m_selected_bkpen
= wxPen(selectedtab_colour
);
805 m_active_close_bmp
= BitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
806 m_disabled_close_bmp
= BitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
808 m_active_left_bmp
= BitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
809 m_disabled_left_bmp
= BitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
811 m_active_right_bmp
= BitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
812 m_disabled_right_bmp
= BitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
814 m_active_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
815 m_disabled_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
819 wxAuiSimpleTabArt::~wxAuiSimpleTabArt()
823 wxAuiTabArt
* wxAuiSimpleTabArt::Clone()
825 return static_cast<wxAuiTabArt
*>(new wxAuiSimpleTabArt
);
829 void wxAuiSimpleTabArt::SetFlags(unsigned int flags
)
834 void wxAuiSimpleTabArt::SetSizingInfo(const wxSize
& tab_ctrl_size
,
837 m_fixed_tab_width
= 100;
839 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
841 if (m_flags
& wxAUI_NB_CLOSE_BUTTON
)
842 tot_width
-= m_active_close_bmp
.GetWidth();
843 if (m_flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
844 tot_width
-= m_active_windowlist_bmp
.GetWidth();
848 m_fixed_tab_width
= tot_width
/(int)tab_count
;
852 if (m_fixed_tab_width
< 100)
853 m_fixed_tab_width
= 100;
855 if (m_fixed_tab_width
> tot_width
/2)
856 m_fixed_tab_width
= tot_width
/2;
858 if (m_fixed_tab_width
> 220)
859 m_fixed_tab_width
= 220;
862 void wxAuiSimpleTabArt::DrawBackground(wxDC
& dc
,
863 wxWindow
* WXUNUSED(wnd
),
867 dc
.SetBrush(m_bkbrush
);
868 dc
.SetPen(*wxTRANSPARENT_PEN
);
869 dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2);
872 dc
.SetPen(*wxGREY_PEN
);
873 dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1);
877 // DrawTab() draws an individual tab.
880 // in_rect - rectangle the tab should be confined to
881 // caption - tab's caption
882 // active - whether or not the tab is active
883 // out_rect - actual output rectangle
884 // x_extent - the advance x; where the next tab should start
886 void wxAuiSimpleTabArt::DrawTab(wxDC
& dc
,
888 const wxRect
& in_rect
,
889 const wxString
& caption_text
,
890 const wxBitmap
& bitmap
,
892 int close_button_state
,
893 wxRect
* out_tab_rect
,
894 wxRect
* out_button_rect
,
897 wxCoord normal_textx
, normal_texty
;
898 wxCoord selected_textx
, selected_texty
;
899 wxCoord textx
, texty
;
901 // if the caption is empty, measure some temporary text
902 wxString caption
= caption_text
;
903 if (caption_text
.empty())
906 dc
.SetFont(m_selected_font
);
907 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
909 dc
.SetFont(m_normal_font
);
910 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
912 // figure out the size of the tab
913 wxSize tab_size
= GetTabSize(dc
,
921 wxCoord tab_height
= tab_size
.y
;
922 wxCoord tab_width
= tab_size
.x
;
923 wxCoord tab_x
= in_rect
.x
;
924 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
926 caption
= caption_text
;
928 // select pen, brush and font for the tab to be drawn
932 dc
.SetPen(m_selected_bkpen
);
933 dc
.SetBrush(m_selected_bkbrush
);
934 dc
.SetFont(m_selected_font
);
935 textx
= selected_textx
;
936 texty
= selected_texty
;
940 dc
.SetPen(m_normal_bkpen
);
941 dc
.SetBrush(m_normal_bkbrush
);
942 dc
.SetFont(m_normal_font
);
943 textx
= normal_textx
;
944 texty
= normal_texty
;
952 points
[0].y
= tab_y
+ tab_height
- 1;
953 points
[1].x
= tab_x
+ tab_height
- 3;
954 points
[1].y
= tab_y
+ 2;
955 points
[2].x
= tab_x
+ tab_height
+ 3;
957 points
[3].x
= tab_x
+ tab_width
- 2;
959 points
[4].x
= tab_x
+ tab_width
;
960 points
[4].y
= tab_y
+ 2;
961 points
[5].x
= tab_x
+ tab_width
;
962 points
[5].y
= tab_y
+ tab_height
- 1;
963 points
[6] = points
[0];
965 dc
.SetClippingRegion(in_rect
);
967 dc
.DrawPolygon(WXSIZEOF(points
) - 1, points
);
969 dc
.SetPen(*wxGREY_PEN
);
971 //dc.DrawLines(active ? WXSIZEOF(points) - 1 : WXSIZEOF(points), points);
972 dc
.DrawLines(WXSIZEOF(points
), points
);
977 int close_button_width
= 0;
978 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
980 close_button_width
= m_active_close_bmp
.GetWidth();
981 text_offset
= tab_x
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2);
985 text_offset
= tab_x
+ (tab_height
/3) + (tab_width
/2) - (textx
/2);
988 // set minimum text offset
989 if (text_offset
< tab_x
+ tab_height
)
990 text_offset
= tab_x
+ tab_height
;
992 // chop text if necessary
993 wxString draw_text
= ChopText(dc
,
995 tab_width
- (text_offset
-tab_x
) - close_button_width
);
998 dc
.DrawText(draw_text
,
1000 (tab_y
+ tab_height
)/2 - (texty
/2) + 1);
1003 // draw close button if necessary
1004 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1008 bmp
= m_active_close_bmp
;
1010 bmp
= m_disabled_close_bmp
;
1012 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
1013 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1,
1016 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, close_button_state
);
1018 *out_button_rect
= rect
;
1022 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
1024 dc
.DestroyClippingRegion();
1027 int wxAuiSimpleTabArt::GetIndentSize()
1032 wxSize
wxAuiSimpleTabArt::GetTabSize(wxDC
& dc
,
1033 wxWindow
* WXUNUSED(wnd
),
1034 const wxString
& caption
,
1035 const wxBitmap
& WXUNUSED(bitmap
),
1036 bool WXUNUSED(active
),
1037 int close_button_state
,
1040 wxCoord measured_textx
, measured_texty
;
1042 dc
.SetFont(m_measuring_font
);
1043 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
1045 wxCoord tab_height
= measured_texty
+ 4;
1046 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
1048 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1049 tab_width
+= m_active_close_bmp
.GetWidth();
1051 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
1053 tab_width
= m_fixed_tab_width
;
1056 *x_extent
= tab_width
- (tab_height
/2) - 1;
1058 return wxSize(tab_width
, tab_height
);
1062 void wxAuiSimpleTabArt::DrawButton(wxDC
& dc
,
1063 wxWindow
* WXUNUSED(wnd
),
1064 const wxRect
& in_rect
,
1068 const wxBitmap
& bitmap_override
,
1074 if (bitmap_override
.IsOk())
1076 bmp
= bitmap_override
;
1082 case wxAUI_BUTTON_CLOSE
:
1083 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1084 bmp
= m_disabled_close_bmp
;
1086 bmp
= m_active_close_bmp
;
1088 case wxAUI_BUTTON_LEFT
:
1089 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1090 bmp
= m_disabled_left_bmp
;
1092 bmp
= m_active_left_bmp
;
1094 case wxAUI_BUTTON_RIGHT
:
1095 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1096 bmp
= m_disabled_right_bmp
;
1098 bmp
= m_active_right_bmp
;
1100 case wxAUI_BUTTON_WINDOWLIST
:
1101 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1102 bmp
= m_disabled_windowlist_bmp
;
1104 bmp
= m_active_windowlist_bmp
;
1114 if (orientation
== wxLEFT
)
1116 rect
.SetX(in_rect
.x
);
1117 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
1118 rect
.SetWidth(bmp
.GetWidth());
1119 rect
.SetHeight(bmp
.GetHeight());
1123 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
1124 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
1125 bmp
.GetWidth(), bmp
.GetHeight());
1129 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, button_state
);
1135 int wxAuiSimpleTabArt::ShowWindowList(wxWindow
* wnd
,
1136 const wxArrayString
& items
,
1141 size_t i
, count
= items
.GetCount();
1142 for (i
= 0; i
< count
; ++i
)
1144 menuPopup
.AppendCheckItem(1000+i
, items
.Item(i
));
1147 if (active_idx
!= -1)
1149 menuPopup
.Check(1000+active_idx
, true);
1152 // find out where to put the popup menu of window
1153 // items. Subtract 100 for now to center the menu
1154 // a bit, until a better mechanism can be implemented
1155 wxPoint pt
= ::wxGetMousePosition();
1156 pt
= wnd
->ScreenToClient(pt
);
1162 // find out the screen coordinate at the bottom of the tab ctrl
1163 wxRect cli_rect
= wnd
->GetClientRect();
1164 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
1166 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
1167 wnd
->PushEventHandler(cc
);
1168 wnd
->PopupMenu(&menuPopup
, pt
);
1169 int command
= cc
->GetCommandId();
1170 wnd
->PopEventHandler(true);
1172 if (command
>= 1000)
1173 return command
-1000;
1178 int wxAuiSimpleTabArt::GetBestTabCtrlSize(wxWindow
* wnd
,
1179 wxAuiNotebookPageArray
& WXUNUSED(pages
))
1182 dc
.SetFont(m_measuring_font
);
1184 wxSize s
= GetTabSize(dc
,
1189 wxAUI_BUTTON_STATE_HIDDEN
,
1194 void wxAuiSimpleTabArt::SetNormalFont(const wxFont
& font
)
1196 m_normal_font
= font
;
1199 void wxAuiSimpleTabArt::SetSelectedFont(const wxFont
& font
)
1201 m_selected_font
= font
;
1204 void wxAuiSimpleTabArt::SetMeasuringFont(const wxFont
& font
)
1206 m_measuring_font
= font
;
1212 // -- wxAuiTabContainer class implementation --
1215 // wxAuiTabContainer is a class which contains information about each
1216 // tab. It also can render an entire tab control to a specified DC.
1217 // It's not a window class itself, because this code will be used by
1218 // the wxFrameMananger, where it is disadvantageous to have separate
1219 // windows for each tab control in the case of "docked tabs"
1221 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window
1222 // which can be used as a tab control in the normal sense.
1225 wxAuiTabContainer::wxAuiTabContainer()
1229 m_art
= new wxAuiDefaultTabArt
;
1231 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
1232 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
1233 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
1234 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
1237 wxAuiTabContainer::~wxAuiTabContainer()
1242 void wxAuiTabContainer::SetArtProvider(wxAuiTabArt
* art
)
1249 m_art
->SetFlags(m_flags
);
1253 wxAuiTabArt
* wxAuiTabContainer::GetArtProvider() const
1258 void wxAuiTabContainer::SetFlags(unsigned int flags
)
1262 // check for new close button settings
1263 RemoveButton(wxAUI_BUTTON_LEFT
);
1264 RemoveButton(wxAUI_BUTTON_RIGHT
);
1265 RemoveButton(wxAUI_BUTTON_WINDOWLIST
);
1266 RemoveButton(wxAUI_BUTTON_CLOSE
);
1269 if (flags
& wxAUI_NB_SCROLL_BUTTONS
)
1271 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
1272 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
1275 if (flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
1277 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
1280 if (flags
& wxAUI_NB_CLOSE_BUTTON
)
1282 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
1287 m_art
->SetFlags(m_flags
);
1291 unsigned int wxAuiTabContainer::GetFlags() const
1297 void wxAuiTabContainer::SetNormalFont(const wxFont
& font
)
1299 m_art
->SetNormalFont(font
);
1302 void wxAuiTabContainer::SetSelectedFont(const wxFont
& font
)
1304 m_art
->SetSelectedFont(font
);
1307 void wxAuiTabContainer::SetMeasuringFont(const wxFont
& font
)
1309 m_art
->SetMeasuringFont(font
);
1312 void wxAuiTabContainer::SetRect(const wxRect
& rect
)
1318 m_art
->SetSizingInfo(rect
.GetSize(), m_pages
.GetCount());
1322 bool wxAuiTabContainer::AddPage(wxWindow
* page
,
1323 const wxAuiNotebookPage
& info
)
1325 wxAuiNotebookPage page_info
;
1327 page_info
.window
= page
;
1329 m_pages
.Add(page_info
);
1331 // let the art provider know how many pages we have
1334 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1340 bool wxAuiTabContainer::InsertPage(wxWindow
* page
,
1341 const wxAuiNotebookPage
& info
,
1344 wxAuiNotebookPage page_info
;
1346 page_info
.window
= page
;
1348 if (idx
>= m_pages
.GetCount())
1349 m_pages
.Add(page_info
);
1351 m_pages
.Insert(page_info
, idx
);
1353 // let the art provider know how many pages we have
1356 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1362 bool wxAuiTabContainer::MovePage(wxWindow
* page
,
1365 int idx
= GetIdxFromWindow(page
);
1369 // get page entry, make a copy of it
1370 wxAuiNotebookPage p
= GetPage(idx
);
1372 // remove old page entry
1375 // insert page where it should be
1376 InsertPage(page
, p
, new_idx
);
1381 bool wxAuiTabContainer::RemovePage(wxWindow
* wnd
)
1383 size_t i
, page_count
= m_pages
.GetCount();
1384 for (i
= 0; i
< page_count
; ++i
)
1386 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1387 if (page
.window
== wnd
)
1389 m_pages
.RemoveAt(i
);
1391 // let the art provider know how many pages we have
1394 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1404 bool wxAuiTabContainer::SetActivePage(wxWindow
* wnd
)
1408 size_t i
, page_count
= m_pages
.GetCount();
1409 for (i
= 0; i
< page_count
; ++i
)
1411 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1412 if (page
.window
== wnd
)
1419 page
.active
= false;
1426 void wxAuiTabContainer::SetNoneActive()
1428 size_t i
, page_count
= m_pages
.GetCount();
1429 for (i
= 0; i
< page_count
; ++i
)
1431 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1432 page
.active
= false;
1436 bool wxAuiTabContainer::SetActivePage(size_t page
)
1438 if (page
>= m_pages
.GetCount())
1441 return SetActivePage(m_pages
.Item(page
).window
);
1444 int wxAuiTabContainer::GetActivePage() const
1446 size_t i
, page_count
= m_pages
.GetCount();
1447 for (i
= 0; i
< page_count
; ++i
)
1449 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1457 wxWindow
* wxAuiTabContainer::GetWindowFromIdx(size_t idx
) const
1459 if (idx
>= m_pages
.GetCount())
1462 return m_pages
[idx
].window
;
1465 int wxAuiTabContainer::GetIdxFromWindow(wxWindow
* wnd
) const
1467 size_t i
, page_count
= m_pages
.GetCount();
1468 for (i
= 0; i
< page_count
; ++i
)
1470 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1471 if (page
.window
== wnd
)
1477 wxAuiNotebookPage
& wxAuiTabContainer::GetPage(size_t idx
)
1479 wxASSERT_MSG(idx
< m_pages
.GetCount(), wxT("Invalid Page index"));
1481 return m_pages
[idx
];
1484 wxAuiNotebookPageArray
& wxAuiTabContainer::GetPages()
1489 size_t wxAuiTabContainer::GetPageCount() const
1491 return m_pages
.GetCount();
1494 void wxAuiTabContainer::AddButton(int id
,
1496 const wxBitmap
& normal_bitmap
,
1497 const wxBitmap
& disabled_bitmap
)
1499 wxAuiTabContainerButton button
;
1501 button
.bitmap
= normal_bitmap
;
1502 button
.dis_bitmap
= disabled_bitmap
;
1503 button
.location
= location
;
1504 button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1506 m_buttons
.Add(button
);
1509 void wxAuiTabContainer::RemoveButton(int id
)
1511 size_t i
, button_count
= m_buttons
.GetCount();
1513 for (i
= 0; i
< button_count
; ++i
)
1515 if (m_buttons
.Item(i
).id
== id
)
1517 m_buttons
.RemoveAt(i
);
1525 size_t wxAuiTabContainer::GetTabOffset() const
1527 return m_tab_offset
;
1530 void wxAuiTabContainer::SetTabOffset(size_t offset
)
1532 m_tab_offset
= offset
;
1538 // Render() renders the tab catalog to the specified DC
1539 // It is a virtual function and can be overridden to
1540 // provide custom drawing capabilities
1541 void wxAuiTabContainer::Render(wxDC
* raw_dc
, wxWindow
* wnd
)
1543 if (!raw_dc
|| !raw_dc
->IsOk())
1549 size_t page_count
= m_pages
.GetCount();
1550 size_t button_count
= m_buttons
.GetCount();
1552 // create off-screen bitmap
1553 bmp
.Create(m_rect
.GetWidth(), m_rect
.GetHeight());
1554 dc
.SelectObject(bmp
);
1559 // find out if size of tabs is larger than can be
1560 // afforded on screen
1561 int total_width
= 0;
1562 int visible_width
= 0;
1563 for (i
= 0; i
< page_count
; ++i
)
1565 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1567 // determine if a close button is on this tab
1568 bool close_button
= false;
1569 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1570 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1572 close_button
= true;
1577 wxSize size
= m_art
->GetTabSize(dc
,
1583 wxAUI_BUTTON_STATE_NORMAL
:
1584 wxAUI_BUTTON_STATE_HIDDEN
,
1587 if (i
+1 < page_count
)
1588 total_width
+= x_extent
;
1590 total_width
+= size
.x
;
1592 if (i
>= m_tab_offset
)
1594 if (i
+1 < page_count
)
1595 visible_width
+= x_extent
;
1597 visible_width
+= size
.x
;
1601 if (total_width
> m_rect
.GetWidth() || m_tab_offset
!= 0)
1603 // show left/right buttons
1604 for (i
= 0; i
< button_count
; ++i
)
1606 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1607 if (button
.id
== wxAUI_BUTTON_LEFT
||
1608 button
.id
== wxAUI_BUTTON_RIGHT
)
1610 button
.cur_state
&= ~wxAUI_BUTTON_STATE_HIDDEN
;
1616 // hide left/right buttons
1617 for (i
= 0; i
< button_count
; ++i
)
1619 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1620 if (button
.id
== wxAUI_BUTTON_LEFT
||
1621 button
.id
== wxAUI_BUTTON_RIGHT
)
1623 button
.cur_state
|= wxAUI_BUTTON_STATE_HIDDEN
;
1628 // determine whether left button should be enabled
1629 for (i
= 0; i
< button_count
; ++i
)
1631 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1632 if (button
.id
== wxAUI_BUTTON_LEFT
)
1634 if (m_tab_offset
== 0)
1635 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
1637 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
1639 if (button
.id
== wxAUI_BUTTON_RIGHT
)
1641 if (visible_width
< m_rect
.GetWidth() - ((int)button_count
*16))
1642 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
1644 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
1651 m_art
->DrawBackground(dc
, wnd
, m_rect
);
1654 int left_buttons_width
= 0;
1655 int right_buttons_width
= 0;
1659 // draw the buttons on the right side
1660 offset
= m_rect
.x
+ m_rect
.width
;
1661 for (i
= 0; i
< button_count
; ++i
)
1663 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
1665 if (button
.location
!= wxRIGHT
)
1667 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
1670 wxRect button_rect
= m_rect
;
1671 button_rect
.SetY(1);
1672 button_rect
.SetWidth(offset
);
1674 m_art
->DrawButton(dc
,
1683 offset
-= button
.rect
.GetWidth();
1684 right_buttons_width
+= button
.rect
.GetWidth();
1691 // draw the buttons on the left side
1693 for (i
= 0; i
< button_count
; ++i
)
1695 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
1697 if (button
.location
!= wxLEFT
)
1699 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
1702 wxRect
button_rect(offset
, 1, 1000, m_rect
.height
);
1704 m_art
->DrawButton(dc
,
1713 offset
+= button
.rect
.GetWidth();
1714 left_buttons_width
+= button
.rect
.GetWidth();
1717 offset
= left_buttons_width
;
1720 offset
+= m_art
->GetIndentSize();
1723 // prepare the tab-close-button array
1724 // make sure tab button entries which aren't used are marked as hidden
1725 for (i
= page_count
; i
< m_tab_close_buttons
.GetCount(); ++i
)
1726 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1728 // make sure there are enough tab button entries to accommodate all tabs
1729 while (m_tab_close_buttons
.GetCount() < page_count
)
1731 wxAuiTabContainerButton tempbtn
;
1732 tempbtn
.id
= wxAUI_BUTTON_CLOSE
;
1733 tempbtn
.location
= wxCENTER
;
1734 tempbtn
.cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1735 m_tab_close_buttons
.Add(tempbtn
);
1739 // buttons before the tab offset must be set to hidden
1740 for (i
= 0; i
< m_tab_offset
; ++i
)
1742 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1748 size_t active
= 999;
1749 int active_offset
= 0;
1753 wxRect rect
= m_rect
;
1755 rect
.height
= m_rect
.height
;
1757 for (i
= m_tab_offset
; i
< page_count
; ++i
)
1759 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1760 wxAuiTabContainerButton
& tab_button
= m_tab_close_buttons
.Item(i
);
1762 // determine if a close button is on this tab
1763 bool close_button
= false;
1764 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1765 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1767 close_button
= true;
1768 if (tab_button
.cur_state
== wxAUI_BUTTON_STATE_HIDDEN
)
1770 tab_button
.id
= wxAUI_BUTTON_CLOSE
;
1771 tab_button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1772 tab_button
.location
= wxCENTER
;
1777 tab_button
.cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1781 rect
.width
= m_rect
.width
- right_buttons_width
- offset
- 2;
1783 if (rect
.width
<= 0)
1792 tab_button
.cur_state
,
1800 active_offset
= offset
;
1808 // make sure to deactivate buttons which are off the screen to the right
1809 for (++i
; i
< m_tab_close_buttons
.GetCount(); ++i
)
1811 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1815 // draw the active tab again so it stands in the foreground
1816 if (active
>= m_tab_offset
&& active
< m_pages
.GetCount())
1818 wxAuiNotebookPage
& page
= m_pages
.Item(active
);
1820 wxAuiTabContainerButton
& tab_button
= m_tab_close_buttons
.Item(active
);
1822 // determine if a close button is on this tab
1823 bool close_button
= false;
1824 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1825 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1827 close_button
= true;
1830 rect
.x
= active_offset
;
1837 tab_button
.cur_state
,
1844 raw_dc
->Blit(m_rect
.x
, m_rect
.y
,
1845 m_rect
.GetWidth(), m_rect
.GetHeight(),
1850 // TabHitTest() tests if a tab was hit, passing the window pointer
1851 // back if that condition was fulfilled. The function returns
1852 // true if a tab was hit, otherwise false
1853 bool wxAuiTabContainer::TabHitTest(int x
, int y
, wxWindow
** hit
) const
1855 if (!m_rect
.Contains(x
,y
))
1858 wxAuiTabContainerButton
* btn
= NULL
;
1859 if (ButtonHitTest(x
, y
, &btn
))
1861 if (m_buttons
.Index(*btn
) != wxNOT_FOUND
)
1865 size_t i
, page_count
= m_pages
.GetCount();
1867 for (i
= m_tab_offset
; i
< page_count
; ++i
)
1869 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1870 if (page
.rect
.Contains(x
,y
))
1881 // ButtonHitTest() tests if a button was hit. The function returns
1882 // true if a button was hit, otherwise false
1883 bool wxAuiTabContainer::ButtonHitTest(int x
, int y
,
1884 wxAuiTabContainerButton
** hit
) const
1886 if (!m_rect
.Contains(x
,y
))
1889 size_t i
, button_count
;
1892 button_count
= m_buttons
.GetCount();
1893 for (i
= 0; i
< button_count
; ++i
)
1895 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1896 if (button
.rect
.Contains(x
,y
) &&
1897 !(button
.cur_state
& (wxAUI_BUTTON_STATE_HIDDEN
|
1898 wxAUI_BUTTON_STATE_DISABLED
)))
1906 button_count
= m_tab_close_buttons
.GetCount();
1907 for (i
= 0; i
< button_count
; ++i
)
1909 wxAuiTabContainerButton
& button
= m_tab_close_buttons
.Item(i
);
1910 if (button
.rect
.Contains(x
,y
) &&
1911 !(button
.cur_state
& (wxAUI_BUTTON_STATE_HIDDEN
|
1912 wxAUI_BUTTON_STATE_DISABLED
)))
1925 // the utility function ShowWnd() is the same as show,
1926 // except it handles wxAuiMDIChildFrame windows as well,
1927 // as the Show() method on this class is "unplugged"
1928 static void ShowWnd(wxWindow
* wnd
, bool show
)
1930 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
1932 wxAuiMDIChildFrame
* cf
= (wxAuiMDIChildFrame
*)wnd
;
1942 // DoShowHide() this function shows the active window, then
1943 // hides all of the other windows (in that order)
1944 void wxAuiTabContainer::DoShowHide()
1946 wxAuiNotebookPageArray
& pages
= GetPages();
1947 size_t i
, page_count
= pages
.GetCount();
1949 // show new active page first
1950 for (i
= 0; i
< page_count
; ++i
)
1952 wxAuiNotebookPage
& page
= pages
.Item(i
);
1955 ShowWnd(page
.window
, true);
1960 // hide all other pages
1961 for (i
= 0; i
< page_count
; ++i
)
1963 wxAuiNotebookPage
& page
= pages
.Item(i
);
1964 ShowWnd(page
.window
, page
.active
);
1973 // -- wxAuiTabCtrl class implementation --
1977 BEGIN_EVENT_TABLE(wxAuiTabCtrl
, wxControl
)
1978 EVT_PAINT(wxAuiTabCtrl::OnPaint
)
1979 EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground
)
1980 EVT_SIZE(wxAuiTabCtrl::OnSize
)
1981 EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown
)
1982 EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp
)
1983 EVT_MOTION(wxAuiTabCtrl::OnMotion
)
1984 EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow
)
1985 EVT_AUINOTEBOOK_BUTTON(-1, wxAuiTabCtrl::OnButton
)
1989 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow
* parent
,
1993 long style
) : wxControl(parent
, id
, pos
, size
, style
)
1995 m_click_pt
= wxDefaultPosition
;
1996 m_is_dragging
= false;
1997 m_hover_button
= NULL
;
1998 m_pressed_button
= NULL
;
2001 wxAuiTabCtrl::~wxAuiTabCtrl()
2005 void wxAuiTabCtrl::OnPaint(wxPaintEvent
&)
2009 dc
.SetFont(GetFont());
2011 if (GetPageCount() > 0)
2015 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent
& WXUNUSED(evt
))
2019 void wxAuiTabCtrl::OnSize(wxSizeEvent
& evt
)
2021 wxSize s
= evt
.GetSize();
2022 wxRect
r(0, 0, s
.GetWidth(), s
.GetHeight());
2026 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent
& evt
)
2029 m_click_pt
= wxDefaultPosition
;
2030 m_is_dragging
= false;
2032 m_pressed_button
= NULL
;
2036 if (TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
2038 int new_selection
= GetIdxFromWindow(wnd
);
2040 if (new_selection
!= GetActivePage())
2042 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2043 e
.SetSelection(new_selection
);
2044 e
.SetOldSelection(GetActivePage());
2045 e
.SetEventObject(this);
2046 GetEventHandler()->ProcessEvent(e
);
2049 m_click_pt
.x
= evt
.m_x
;
2050 m_click_pt
.y
= evt
.m_y
;
2056 m_pressed_button
= m_hover_button
;
2057 m_pressed_button
->cur_state
= wxAUI_BUTTON_STATE_PRESSED
;
2063 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent
& evt
)
2065 if (GetCapture() == this)
2070 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, m_windowId
);
2071 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2072 evt
.SetOldSelection(evt
.GetSelection());
2073 evt
.SetEventObject(this);
2074 GetEventHandler()->ProcessEvent(evt
);
2078 if (m_pressed_button
)
2080 // make sure we're still clicking the button
2081 wxAuiTabContainerButton
* button
= NULL
;
2082 if (!ButtonHitTest(evt
.m_x
, evt
.m_y
, &button
))
2085 if (button
!= m_pressed_button
)
2087 m_pressed_button
= NULL
;
2094 if (!(m_pressed_button
->cur_state
& wxAUI_BUTTON_STATE_DISABLED
))
2096 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, m_windowId
);
2097 evt
.SetInt(m_pressed_button
->id
);
2098 evt
.SetEventObject(this);
2099 GetEventHandler()->ProcessEvent(evt
);
2102 m_pressed_button
= NULL
;
2105 m_click_pt
= wxDefaultPosition
;
2106 m_is_dragging
= false;
2110 void wxAuiTabCtrl::OnMotion(wxMouseEvent
& evt
)
2112 wxPoint pos
= evt
.GetPosition();
2114 // check if the mouse is hovering above a button
2115 wxAuiTabContainerButton
* button
;
2116 if (ButtonHitTest(pos
.x
, pos
.y
, &button
))
2118 if (m_hover_button
&& button
!= m_hover_button
)
2120 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2121 m_hover_button
= NULL
;
2126 if (button
->cur_state
!= wxAUI_BUTTON_STATE_HOVER
)
2128 button
->cur_state
= wxAUI_BUTTON_STATE_HOVER
;
2131 m_hover_button
= button
;
2139 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2140 m_hover_button
= NULL
;
2147 if (!evt
.LeftIsDown() || m_click_pt
== wxDefaultPosition
)
2152 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, m_windowId
);
2153 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2154 evt
.SetOldSelection(evt
.GetSelection());
2155 evt
.SetEventObject(this);
2156 GetEventHandler()->ProcessEvent(evt
);
2161 int drag_x_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_X
);
2162 int drag_y_threshold
= wxSystemSettings::GetMetric(wxSYS_DRAG_Y
);
2164 if (abs(pos
.x
- m_click_pt
.x
) > drag_x_threshold
||
2165 abs(pos
.y
- m_click_pt
.y
) > drag_y_threshold
)
2167 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, m_windowId
);
2168 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2169 evt
.SetOldSelection(evt
.GetSelection());
2170 evt
.SetEventObject(this);
2171 GetEventHandler()->ProcessEvent(evt
);
2173 m_is_dragging
= true;
2177 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
))
2181 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2182 m_hover_button
= NULL
;
2188 void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent
& event
)
2190 int button
= event
.GetInt();
2192 if (button
== wxAUI_BUTTON_LEFT
|| button
== wxAUI_BUTTON_RIGHT
)
2194 if (button
== wxAUI_BUTTON_LEFT
)
2196 if (GetTabOffset() > 0)
2198 SetTabOffset(GetTabOffset()-1);
2205 SetTabOffset(GetTabOffset()+1);
2210 else if (button
== wxAUI_BUTTON_WINDOWLIST
)
2214 size_t i
, page_count
= m_pages
.GetCount();
2215 for (i
= 0; i
< page_count
; ++i
)
2217 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
2218 as
.Add(page
.caption
);
2221 int idx
= GetArtProvider()->ShowWindowList(this, as
, GetActivePage());
2225 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2226 e
.SetSelection(idx
);
2227 e
.SetOldSelection(GetActivePage());
2228 e
.SetEventObject(this);
2229 GetEventHandler()->ProcessEvent(e
);
2238 // wxTabFrame is an interesting case. It's important that all child pages
2239 // of the multi-notebook control are all actually children of that control
2240 // (and not grandchildren). wxTabFrame facilitates this. There is one
2241 // instance of wxTabFrame for each tab control inside the multi-notebook.
2242 // It's important to know that wxTabFrame is not a real window, but it merely
2243 // used to capture the dimensions/positioning of the internal tab control and
2244 // it's managed page windows
2246 class wxTabFrame
: public wxWindow
2253 m_rect
= wxRect(0,0,200,200);
2254 m_tab_ctrl_height
= 20;
2257 void SetTabCtrlHeight(int h
)
2259 m_tab_ctrl_height
= h
;
2262 void DoSetSize(int x
, int y
,
2263 int width
, int height
,
2264 int WXUNUSED(sizeFlags
= wxSIZE_AUTO
))
2266 m_rect
= wxRect(x
, y
, width
, height
);
2270 void DoGetClientSize(int* x
, int* y
) const
2276 bool Show( bool WXUNUSED(show
= true) ) { return false; }
2283 m_tab_rect
= wxRect(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
);
2284 m_tabs
->SetSize(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
);
2285 m_tabs
->SetRect(wxRect(0, 0, m_rect
.width
, m_tab_ctrl_height
));
2289 wxAuiNotebookPageArray
& pages
= m_tabs
->GetPages();
2290 size_t i
, page_count
= pages
.GetCount();
2292 for (i
= 0; i
< page_count
; ++i
)
2294 wxAuiNotebookPage
& page
= pages
.Item(i
);
2295 page
.window
->SetSize(m_rect
.x
, m_rect
.y
+ m_tab_ctrl_height
,
2296 m_rect
.width
, m_rect
.height
- m_tab_ctrl_height
);
2298 if (page
.window
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
2300 wxAuiMDIChildFrame
* wnd
= (wxAuiMDIChildFrame
*)page
.window
;
2301 wnd
->ApplyMDIChildFrameRect();
2306 void DoGetSize(int* x
, int* y
) const
2309 *x
= m_rect
.GetWidth();
2311 *y
= m_rect
.GetHeight();
2323 wxAuiTabCtrl
* m_tabs
;
2324 int m_tab_ctrl_height
;
2331 // -- wxAuiNotebook class implementation --
2333 BEGIN_EVENT_TABLE(wxAuiNotebook
, wxControl
)
2334 //EVT_ERASE_BACKGROUND(wxAuiNotebook::OnEraseBackground)
2335 //EVT_SIZE(wxAuiNotebook::OnSize)
2336 //EVT_LEFT_DOWN(wxAuiNotebook::OnLeftDown)
2337 EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocus
)
2338 EVT_COMMAND_RANGE(10000, 10100,
2339 wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
,
2340 wxAuiNotebook::OnTabClicked
)
2341 EVT_COMMAND_RANGE(10000, 10100,
2342 wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
,
2343 wxAuiNotebook::OnTabBeginDrag
)
2344 EVT_COMMAND_RANGE(10000, 10100,
2345 wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
,
2346 wxAuiNotebook::OnTabEndDrag
)
2347 EVT_COMMAND_RANGE(10000, 10100,
2348 wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
,
2349 wxAuiNotebook::OnTabDragMotion
)
2350 EVT_COMMAND_RANGE(10000, 10100,
2351 wxEVT_COMMAND_AUINOTEBOOK_BUTTON
,
2352 wxAuiNotebook::OnTabButton
)
2355 wxAuiNotebook::wxAuiNotebook()
2358 m_tab_id_counter
= 10000;
2360 m_tab_ctrl_height
= 20;
2363 wxAuiNotebook::wxAuiNotebook(wxWindow
*parent
,
2367 long style
) : wxControl(parent
, id
, pos
, size
, style
)
2369 InitNotebook(style
);
2372 bool wxAuiNotebook::Create(wxWindow
* parent
,
2378 if (!wxControl::Create(parent
, id
, pos
, size
, style
))
2381 InitNotebook(style
);
2386 // InitNotebook() contains common initialization
2387 // code called by all constructors
2388 void wxAuiNotebook::InitNotebook(long style
)
2391 m_tab_id_counter
= 10000;
2393 m_tab_ctrl_height
= 20;
2394 m_flags
= (unsigned int)style
;
2396 m_normal_font
= *wxNORMAL_FONT
;
2397 m_selected_font
= *wxNORMAL_FONT
;
2398 m_selected_font
.SetWeight(wxBOLD
);
2400 SetArtProvider(new wxAuiDefaultTabArt
);
2402 m_dummy_wnd
= new wxWindow(this, wxID_ANY
, wxPoint(0,0), wxSize(0,0));
2403 m_dummy_wnd
->SetSize(200, 200);
2404 m_dummy_wnd
->Show(false);
2406 m_mgr
.SetManagedWindow(this);
2408 m_mgr
.AddPane(m_dummy_wnd
,
2409 wxAuiPaneInfo().Name(wxT("dummy")).Bottom().Show(false));
2414 wxAuiNotebook::~wxAuiNotebook()
2419 void wxAuiNotebook::SetArtProvider(wxAuiTabArt
* art
)
2421 m_tabs
.SetArtProvider(art
);
2423 SetTabCtrlHeight(CalculateTabCtrlHeight());
2426 void wxAuiNotebook::SetTabCtrlHeight(int height
)
2428 // if the tab control height needs to change, update
2429 // all of our tab controls with the new height
2430 if (m_tab_ctrl_height
!= height
)
2432 wxAuiTabArt
* art
= m_tabs
.GetArtProvider();
2434 m_tab_ctrl_height
= height
;
2436 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2437 size_t i
, pane_count
= all_panes
.GetCount();
2438 for (i
= 0; i
< pane_count
; ++i
)
2440 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2441 if (pane
.name
== wxT("dummy"))
2443 wxTabFrame
* tab_frame
= (wxTabFrame
*)pane
.window
;
2444 wxAuiTabCtrl
* tabctrl
= tab_frame
->m_tabs
;
2445 tab_frame
->SetTabCtrlHeight(m_tab_ctrl_height
);
2446 tabctrl
->SetArtProvider(art
->Clone());
2447 tab_frame
->DoSizing();
2452 int wxAuiNotebook::CalculateTabCtrlHeight()
2454 // find out new best tab height
2455 wxAuiTabArt
* art
= m_tabs
.GetArtProvider();
2457 return art
->GetBestTabCtrlSize(this, m_tabs
.GetPages());
2461 wxAuiTabArt
* wxAuiNotebook::GetArtProvider() const
2463 return m_tabs
.GetArtProvider();
2466 void wxAuiNotebook::SetWindowStyleFlag(long style
)
2468 wxControl::SetWindowStyleFlag(style
);
2470 m_flags
= (unsigned int)style
;
2472 // if the control is already initialized
2473 if (m_mgr
.GetManagedWindow() == (wxWindow
*)this)
2475 // let all of the tab children know about the new style
2477 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2478 size_t i
, pane_count
= all_panes
.GetCount();
2479 for (i
= 0; i
< pane_count
; ++i
)
2481 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2482 if (pane
.name
== wxT("dummy"))
2484 wxTabFrame
* tabframe
= (wxTabFrame
*)pane
.window
;
2485 wxAuiTabCtrl
* tabctrl
= tabframe
->m_tabs
;
2486 tabctrl
->SetFlags(m_flags
);
2487 tabframe
->DoSizing();
2495 bool wxAuiNotebook::AddPage(wxWindow
* page
,
2496 const wxString
& caption
,
2498 const wxBitmap
& bitmap
)
2500 return InsertPage(GetPageCount(), page
, caption
, select
, bitmap
);
2503 bool wxAuiNotebook::InsertPage(size_t page_idx
,
2505 const wxString
& caption
,
2507 const wxBitmap
& bitmap
)
2509 wxAuiNotebookPage info
;
2511 info
.caption
= caption
;
2512 info
.bitmap
= bitmap
;
2513 info
.active
= false;
2515 // if there are currently no tabs, the first added
2516 // tab must be active
2517 if (m_tabs
.GetPageCount() == 0)
2520 m_tabs
.InsertPage(page
, info
, page_idx
);
2522 wxAuiTabCtrl
* active_tabctrl
= GetActiveTabCtrl();
2523 if (page_idx
>= active_tabctrl
->GetPageCount())
2524 active_tabctrl
->AddPage(page
, info
);
2526 active_tabctrl
->InsertPage(page
, info
, page_idx
);
2528 SetTabCtrlHeight(CalculateTabCtrlHeight());
2530 active_tabctrl
->DoShowHide();
2534 int idx
= m_tabs
.GetIdxFromWindow(page
);
2535 wxASSERT_MSG(idx
!= -1, wxT("Invalid Page index returned on wxAuiNotebook::InsertPage()"));
2544 // DeletePage() removes a tab from the multi-notebook,
2545 // and destroys the window as well
2546 bool wxAuiNotebook::DeletePage(size_t page_idx
)
2548 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
2550 if (!RemovePage(page_idx
))
2553 // actually destroy the window now
2554 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
2556 // delete the child frame with pending delete, as is
2557 // customary with frame windows
2558 if (!wxPendingDelete
.Member(wnd
))
2559 wxPendingDelete
.Append(wnd
);
2571 // RemovePage() removes a tab from the multi-notebook,
2572 // but does not destroy the window
2573 bool wxAuiNotebook::RemovePage(size_t page_idx
)
2575 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
2576 wxWindow
* new_active
= NULL
;
2578 // find out which onscreen tab ctrl owns this tab
2581 if (!FindTab(wnd
, &ctrl
, &ctrl_idx
))
2584 // find a new page and set it as active
2585 int new_idx
= ctrl_idx
+1;
2586 if (new_idx
>= (int)ctrl
->GetPageCount())
2587 new_idx
= ctrl_idx
-1;
2589 if (new_idx
>= 0 && new_idx
< (int)ctrl
->GetPageCount())
2591 new_active
= ctrl
->GetWindowFromIdx(new_idx
);
2595 // set the active page to the first page that
2596 // isn't the one being deleted
2597 size_t i
, page_count
= m_tabs
.GetPageCount();
2598 for (i
= 0; i
< page_count
; ++i
)
2600 wxWindow
* w
= m_tabs
.GetWindowFromIdx(i
);
2603 new_active
= m_tabs
.GetWindowFromIdx(i
);
2609 // remove the tab from main catalog
2610 if (!m_tabs
.RemovePage(wnd
))
2613 // remove the tab from the onscreen tab ctrl
2614 ctrl
->RemovePage(wnd
);
2617 RemoveEmptyTabFrames();
2619 // set new active pane
2623 SetSelection(m_tabs
.GetIdxFromWindow(new_active
));
2629 // GetPageIndex() returns the index of the page, or -1 if the
2630 // page could not be located in the notebook
2631 int wxAuiNotebook::GetPageIndex(wxWindow
* page_wnd
) const
2633 return m_tabs
.GetIdxFromWindow(page_wnd
);
2638 // SetPageText() changes the tab caption of the specified page
2639 bool wxAuiNotebook::SetPageText(size_t page_idx
, const wxString
& text
)
2641 if (page_idx
>= m_tabs
.GetPageCount())
2644 // update our own tab catalog
2645 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2646 page_info
.caption
= text
;
2648 // update what's on screen
2651 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
2653 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
2654 info
.caption
= text
;
2663 bool wxAuiNotebook::SetPageBitmap(size_t page_idx
, const wxBitmap
& bitmap
)
2665 if (page_idx
>= m_tabs
.GetPageCount())
2668 // update our own tab catalog
2669 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2670 page_info
.bitmap
= bitmap
;
2672 // tab height might have changed
2673 SetTabCtrlHeight(CalculateTabCtrlHeight());
2675 // update what's on screen
2678 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
2680 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
2681 info
.bitmap
= bitmap
;
2690 // GetSelection() returns the index of the currently active page
2691 int wxAuiNotebook::GetSelection() const
2696 // SetSelection() sets the currently active page
2697 size_t wxAuiNotebook::SetSelection(size_t new_page
)
2699 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(new_page
);
2703 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2704 evt
.SetSelection(new_page
);
2705 evt
.SetOldSelection(m_curpage
);
2706 evt
.SetEventObject(this);
2707 if (!GetEventHandler()->ProcessEvent(evt
) || evt
.IsAllowed())
2709 int old_curpage
= m_curpage
;
2710 m_curpage
= new_page
;
2712 // program allows the page change
2713 evt
.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
);
2714 (void)GetEventHandler()->ProcessEvent(evt
);
2719 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
2721 m_tabs
.SetActivePage(wnd
);
2723 ctrl
->SetActivePage(ctrl_idx
);
2730 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2731 size_t i
, pane_count
= all_panes
.GetCount();
2732 for (i
= 0; i
< pane_count
; ++i
)
2734 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2735 if (pane
.name
== wxT("dummy"))
2737 wxAuiTabCtrl
* tabctrl
= ((wxTabFrame
*)pane
.window
)->m_tabs
;
2738 if (tabctrl
!= ctrl
)
2739 tabctrl
->SetSelectedFont(m_normal_font
);
2741 tabctrl
->SetSelectedFont(m_selected_font
);
2754 // GetPageCount() returns the total number of
2755 // pages managed by the multi-notebook
2756 size_t wxAuiNotebook::GetPageCount() const
2758 return m_tabs
.GetPageCount();
2761 // GetPage() returns the wxWindow pointer of the
2763 wxWindow
* wxAuiNotebook::GetPage(size_t page_idx
) const
2765 wxASSERT(page_idx
< m_tabs
.GetPageCount());
2767 return m_tabs
.GetWindowFromIdx(page_idx
);
2770 // DoSizing() performs all sizing operations in each tab control
2771 void wxAuiNotebook::DoSizing()
2773 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2774 size_t i
, pane_count
= all_panes
.GetCount();
2775 for (i
= 0; i
< pane_count
; ++i
)
2777 if (all_panes
.Item(i
).name
== wxT("dummy"))
2780 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2781 tabframe
->DoSizing();
2785 // GetActiveTabCtrl() returns the active tab control. It is
2786 // called to determine which control gets new windows being added
2787 wxAuiTabCtrl
* wxAuiNotebook::GetActiveTabCtrl()
2789 if (m_curpage
>= 0 && m_curpage
< (int)m_tabs
.GetPageCount())
2794 // find the tab ctrl with the current page
2795 if (FindTab(m_tabs
.GetPage(m_curpage
).window
,
2802 // no current page, just find the first tab ctrl
2803 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2804 size_t i
, pane_count
= all_panes
.GetCount();
2805 for (i
= 0; i
< pane_count
; ++i
)
2807 if (all_panes
.Item(i
).name
== wxT("dummy"))
2810 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2811 return tabframe
->m_tabs
;
2814 // If there is no tabframe at all, create one
2815 wxTabFrame
* tabframe
= new wxTabFrame
;
2816 tabframe
->SetTabCtrlHeight(m_tab_ctrl_height
);
2817 tabframe
->m_tabs
= new wxAuiTabCtrl(this,
2822 tabframe
->m_tabs
->SetFlags(m_flags
);
2823 tabframe
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
2824 m_mgr
.AddPane(tabframe
,
2825 wxAuiPaneInfo().Center().CaptionVisible(false));
2829 return tabframe
->m_tabs
;
2832 // FindTab() finds the tab control that currently contains the window as well
2833 // as the index of the window in the tab control. It returns true if the
2834 // window was found, otherwise false.
2835 bool wxAuiNotebook::FindTab(wxWindow
* page
, wxAuiTabCtrl
** ctrl
, int* idx
)
2837 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2838 size_t i
, pane_count
= all_panes
.GetCount();
2839 for (i
= 0; i
< pane_count
; ++i
)
2841 if (all_panes
.Item(i
).name
== wxT("dummy"))
2844 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2846 int page_idx
= tabframe
->m_tabs
->GetIdxFromWindow(page
);
2849 *ctrl
= tabframe
->m_tabs
;
2859 void wxAuiNotebook::OnEraseBackground(wxEraseEvent
&)
2863 void wxAuiNotebook::OnSize(wxSizeEvent
&)
2867 void wxAuiNotebook::OnTabClicked(wxCommandEvent
& command_evt
)
2869 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
2871 wxAuiTabCtrl
* ctrl
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2872 wxASSERT(ctrl
!= NULL
);
2874 wxWindow
* wnd
= ctrl
->GetWindowFromIdx(evt
.GetSelection());
2875 wxASSERT(wnd
!= NULL
);
2877 int idx
= m_tabs
.GetIdxFromWindow(wnd
);
2878 wxASSERT(idx
!= -1);
2883 void wxAuiNotebook::OnTabBeginDrag(wxCommandEvent
&)
2888 void wxAuiNotebook::OnTabDragMotion(wxCommandEvent
& evt
)
2890 wxPoint screen_pt
= ::wxGetMousePosition();
2891 wxPoint client_pt
= ScreenToClient(screen_pt
);
2894 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
2895 wxAuiTabCtrl
* dest_tabs
= GetTabCtrlFromPoint(client_pt
);
2897 if (dest_tabs
== src_tabs
)
2901 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
2904 // always hide the hint for inner-tabctrl drag
2907 // if tab moving is not allowed, leave
2908 if (!(m_flags
& wxAUI_NB_TAB_MOVE
))
2913 wxPoint pt
= dest_tabs
->ScreenToClient(screen_pt
);
2914 wxWindow
* dest_location_tab
;
2916 // this is an inner-tab drag/reposition
2917 if (dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &dest_location_tab
))
2919 int src_idx
= evt
.GetSelection();
2920 int dest_idx
= dest_tabs
->GetIdxFromWindow(dest_location_tab
);
2922 // prevent jumpy drag
2923 if ((src_idx
== dest_idx
) || dest_idx
== -1 ||
2924 (src_idx
> dest_idx
&& m_last_drag_x
<= pt
.x
) ||
2925 (src_idx
< dest_idx
&& m_last_drag_x
>= pt
.x
))
2927 m_last_drag_x
= pt
.x
;
2932 wxWindow
* src_tab
= dest_tabs
->GetWindowFromIdx(src_idx
);
2933 dest_tabs
->MovePage(src_tab
, dest_idx
);
2934 dest_tabs
->SetActivePage((size_t)dest_idx
);
2935 dest_tabs
->DoShowHide();
2936 dest_tabs
->Refresh();
2937 m_last_drag_x
= pt
.x
;
2945 // if external drag is allowed, check if the tab is being dragged
2946 // over a different wxAuiNotebook control
2947 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
2949 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(screen_pt
);
2951 // if we aren't over any window, stop here
2955 // make sure we are not over the hint window
2956 if (!tab_ctrl
->IsKindOf(CLASSINFO(wxFrame
)))
2960 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
2962 tab_ctrl
= tab_ctrl
->GetParent();
2967 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
2971 wxRect hint_rect
= tab_ctrl
->GetClientRect();
2972 tab_ctrl
->ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
2973 m_mgr
.ShowHint(hint_rect
);
2982 // we are either over a hint window, or not over a tab
2983 // window, and there is no where to drag to, so exit
2990 // if there are less than two panes, split can't happen, so leave
2991 if (m_tabs
.GetPageCount() < 2)
2994 // if tab moving is not allowed, leave
2995 if (!(m_flags
& wxAUI_NB_TAB_SPLIT
))
3001 src_tabs
->SetCursor(wxCursor(wxCURSOR_SIZING
));
3007 wxRect hint_rect
= dest_tabs
->GetRect();
3008 ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
3009 m_mgr
.ShowHint(hint_rect
);
3013 m_mgr
.DrawHintRect(m_dummy_wnd
, client_pt
, zero
);
3019 void wxAuiNotebook::OnTabEndDrag(wxCommandEvent
& command_evt
)
3021 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
3026 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3027 wxAuiTabCtrl
* dest_tabs
= NULL
;
3030 // set cursor back to an arrow
3031 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
3034 // get the mouse position, which will be used to determine the drop point
3035 wxPoint mouse_screen_pt
= ::wxGetMousePosition();
3036 wxPoint mouse_client_pt
= ScreenToClient(mouse_screen_pt
);
3040 // check for an external move
3041 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
3043 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(mouse_screen_pt
);
3047 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
3049 tab_ctrl
= tab_ctrl
->GetParent();
3054 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
3058 // find out from the destination control
3059 // if it's ok to drop this tab here
3060 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
, m_windowId
);
3061 e
.SetSelection(evt
.GetSelection());
3062 e
.SetOldSelection(evt
.GetSelection());
3063 e
.SetEventObject(this);
3064 e
.SetDragSource(this);
3065 e
.Veto(); // dropping must be explicitly approved by control owner
3067 nb
->GetEventHandler()->ProcessEvent(e
);
3071 // no answer or negative answer
3077 int src_idx
= evt
.GetSelection();
3078 wxWindow
* src_page
= src_tabs
->GetWindowFromIdx(src_idx
);
3080 // get main index of the page
3081 int main_idx
= m_tabs
.GetIdxFromWindow(src_page
);
3083 // make a copy of the page info
3084 wxAuiNotebookPage page_info
= m_tabs
.GetPage((size_t)main_idx
);
3086 // remove the page from the source notebook
3087 RemovePage(main_idx
);
3089 // reparent the page
3090 src_page
->Reparent(nb
);
3093 // found out the insert idx
3094 wxAuiTabCtrl
* dest_tabs
= (wxAuiTabCtrl
*)tab_ctrl
;
3095 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
3097 wxWindow
* target
= NULL
;
3098 int insert_idx
= -1;
3099 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
3102 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
3106 // add the page to the new notebook
3107 if (insert_idx
== -1)
3108 insert_idx
= dest_tabs
->GetPageCount();
3109 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
3110 nb
->m_tabs
.AddPage(page_info
.window
, page_info
);
3113 dest_tabs
->DoShowHide();
3114 dest_tabs
->Refresh();
3116 // set the selection in the destination tab control
3117 nb
->SetSelection(nb
->m_tabs
.GetIdxFromWindow(page_info
.window
));
3127 // only perform a tab split if it's allowed
3128 if ((m_flags
& wxAUI_NB_TAB_SPLIT
) && m_tabs
.GetPageCount() >= 2)
3130 // If the pointer is in an existing tab frame, do a tab insert
3131 wxWindow
* hit_wnd
= ::wxFindWindowAtPoint(mouse_screen_pt
);
3132 wxTabFrame
* tab_frame
= (wxTabFrame
*)GetTabFrameFromTabCtrl(hit_wnd
);
3133 int insert_idx
= -1;
3136 dest_tabs
= tab_frame
->m_tabs
;
3138 if (dest_tabs
== src_tabs
)
3142 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
3143 wxWindow
* target
= NULL
;
3144 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
3147 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
3153 wxRect rect
= m_mgr
.CalculateHintRect(m_dummy_wnd
,
3158 // there is no suitable drop location here, exit out
3163 // If there is no tabframe at all, create one
3164 wxTabFrame
* new_tabs
= new wxTabFrame
;
3165 new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
);
3166 new_tabs
->m_tabs
= new wxAuiTabCtrl(this,
3171 new_tabs
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
3172 new_tabs
->m_tabs
->SetFlags(m_flags
);
3174 m_mgr
.AddPane(new_tabs
,
3175 wxAuiPaneInfo().Bottom().CaptionVisible(false),
3178 dest_tabs
= new_tabs
->m_tabs
;
3183 // remove the page from the source tabs
3184 wxAuiNotebookPage page_info
= src_tabs
->GetPage(evt
.GetSelection());
3185 page_info
.active
= false;
3186 src_tabs
->RemovePage(page_info
.window
);
3187 if (src_tabs
->GetPageCount() > 0)
3189 src_tabs
->SetActivePage((size_t)0);
3190 src_tabs
->DoShowHide();
3191 src_tabs
->Refresh();
3196 // add the page to the destination tabs
3197 if (insert_idx
== -1)
3198 insert_idx
= dest_tabs
->GetPageCount();
3199 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
3201 if (src_tabs
->GetPageCount() == 0)
3203 RemoveEmptyTabFrames();
3207 dest_tabs
->DoShowHide();
3208 dest_tabs
->Refresh();
3210 SetSelection(m_tabs
.GetIdxFromWindow(page_info
.window
));
3216 wxAuiTabCtrl
* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint
& pt
)
3218 // if we've just removed the last tab from the source
3219 // tab set, the remove the tab control completely
3220 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
3221 size_t i
, pane_count
= all_panes
.GetCount();
3222 for (i
= 0; i
< pane_count
; ++i
)
3224 if (all_panes
.Item(i
).name
== wxT("dummy"))
3227 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3228 if (tabframe
->m_tab_rect
.Contains(pt
))
3229 return tabframe
->m_tabs
;
3235 wxWindow
* wxAuiNotebook::GetTabFrameFromTabCtrl(wxWindow
* tab_ctrl
)
3237 // if we've just removed the last tab from the source
3238 // tab set, the remove the tab control completely
3239 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
3240 size_t i
, pane_count
= all_panes
.GetCount();
3241 for (i
= 0; i
< pane_count
; ++i
)
3243 if (all_panes
.Item(i
).name
== wxT("dummy"))
3246 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3247 if (tabframe
->m_tabs
== tab_ctrl
)
3256 void wxAuiNotebook::RemoveEmptyTabFrames()
3258 // if we've just removed the last tab from the source
3259 // tab set, the remove the tab control completely
3260 wxAuiPaneInfoArray all_panes
= m_mgr
.GetAllPanes();
3261 size_t i
, pane_count
= all_panes
.GetCount();
3262 for (i
= 0; i
< pane_count
; ++i
)
3264 if (all_panes
.Item(i
).name
== wxT("dummy"))
3267 wxTabFrame
* tab_frame
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3268 if (tab_frame
->m_tabs
->GetPageCount() == 0)
3270 m_mgr
.DetachPane(tab_frame
);
3272 // use pending delete because sometimes during
3273 // window closing, refreshs are pending
3274 if (!wxPendingDelete
.Member(tab_frame
->m_tabs
))
3275 wxPendingDelete
.Append(tab_frame
->m_tabs
);
3276 //tab_frame->m_tabs->Destroy();
3283 // check to see if there is still a center pane;
3284 // if there isn't, make a frame the center pane
3285 wxAuiPaneInfoArray panes
= m_mgr
.GetAllPanes();
3286 pane_count
= panes
.GetCount();
3287 wxWindow
* first_good
= NULL
;
3288 bool center_found
= false;
3289 for (i
= 0; i
< pane_count
; ++i
)
3291 if (panes
.Item(i
).name
== wxT("dummy"))
3293 if (panes
.Item(i
).dock_direction
== wxAUI_DOCK_CENTRE
)
3294 center_found
= true;
3296 first_good
= panes
.Item(i
).window
;
3299 if (!center_found
&& first_good
)
3301 m_mgr
.GetPane(first_good
).Centre();
3307 void wxAuiNotebook::OnChildFocus(wxChildFocusEvent
& evt
)
3309 int idx
= m_tabs
.GetIdxFromWindow(evt
.GetWindow());
3310 if (idx
!= -1 && idx
!= m_curpage
)
3317 void wxAuiNotebook::OnTabButton(wxCommandEvent
& command_evt
)
3319 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
3320 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3322 int button_id
= evt
.GetInt();
3324 if (button_id
== wxAUI_BUTTON_CLOSE
)
3326 int selection
= tabs
->GetActivePage();
3328 if (selection
!= -1)
3330 wxWindow
* close_wnd
= tabs
->GetWindowFromIdx(selection
);
3333 // ask owner if it's ok to close the tab
3334 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
, m_windowId
);
3335 e
.SetSelection(m_tabs
.GetIdxFromWindow(close_wnd
));
3336 e
.SetOldSelection(evt
.GetSelection());
3337 e
.SetEventObject(this);
3338 GetEventHandler()->ProcessEvent(e
);
3343 if (close_wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
3349 int main_idx
= m_tabs
.GetIdxFromWindow(close_wnd
);
3350 DeletePage(main_idx
);