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__) && !defined(__WXCOCOA__)
412 // set the clipping region for the tab --
413 wxRegion
clipping_region(WXSIZEOF(clip_points
), clip_points
);
414 dc
.SetClippingRegion(clipping_region
);
415 #endif // !wxDFB && !wxCocoa
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
,
737 const wxSize
& required_bmp_size
)
740 dc
.SetFont(m_measuring_font
);
742 // sometimes a standard bitmap size needs to be enforced, especially
743 // if some tabs have bitmaps and others don't. This is important because
744 // it prevents the tab control from resizing when tabs are added.
745 wxBitmap measure_bmp
;
746 if (required_bmp_size
.IsFullySpecified())
748 measure_bmp
.Create(required_bmp_size
.x
,
749 required_bmp_size
.y
);
754 size_t i
, page_count
= pages
.GetCount();
755 for (i
= 0; i
< page_count
; ++i
)
757 wxAuiNotebookPage
& page
= pages
.Item(i
);
760 if (measure_bmp
.IsOk())
765 // we don't use the caption text because we don't
766 // want tab heights to be different in the case
767 // of a very short piece of text on one tab and a very
768 // tall piece of text on another tab
770 wxSize s
= GetTabSize(dc
,
775 wxAUI_BUTTON_STATE_HIDDEN
,
778 max_y
= wxMax(max_y
, s
.y
);
784 void wxAuiDefaultTabArt
::SetNormalFont(const wxFont
& font
)
786 m_normal_font
= font
;
789 void wxAuiDefaultTabArt
::SetSelectedFont(const wxFont
& font
)
791 m_selected_font
= font
;
794 void wxAuiDefaultTabArt
::SetMeasuringFont(const wxFont
& font
)
796 m_measuring_font
= font
;
800 // -- wxAuiSimpleTabArt class implementation --
802 wxAuiSimpleTabArt
::wxAuiSimpleTabArt()
804 m_normal_font
= *wxNORMAL_FONT
;
805 m_selected_font
= *wxNORMAL_FONT
;
806 m_selected_font
.SetWeight(wxBOLD
);
807 m_measuring_font
= m_selected_font
;
810 m_fixed_tab_width
= 100;
812 wxColour base_colour
= wxSystemSettings
::GetColour(wxSYS_COLOUR_3DFACE
);
814 wxColour background_colour
= StepColour(base_colour
, 95);
815 wxColour normaltab_colour
= base_colour
;
816 wxColour selectedtab_colour
= *wxWHITE
;
818 m_bkbrush
= wxBrush(background_colour
);
819 m_normal_bkbrush
= wxBrush(normaltab_colour
);
820 m_normal_bkpen
= wxPen(normaltab_colour
);
821 m_selected_bkbrush
= wxBrush(selectedtab_colour
);
822 m_selected_bkpen
= wxPen(selectedtab_colour
);
824 m_active_close_bmp
= BitmapFromBits(close_bits
, 16, 16, *wxBLACK
);
825 m_disabled_close_bmp
= BitmapFromBits(close_bits
, 16, 16, wxColour(128,128,128));
827 m_active_left_bmp
= BitmapFromBits(left_bits
, 16, 16, *wxBLACK
);
828 m_disabled_left_bmp
= BitmapFromBits(left_bits
, 16, 16, wxColour(128,128,128));
830 m_active_right_bmp
= BitmapFromBits(right_bits
, 16, 16, *wxBLACK
);
831 m_disabled_right_bmp
= BitmapFromBits(right_bits
, 16, 16, wxColour(128,128,128));
833 m_active_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, *wxBLACK
);
834 m_disabled_windowlist_bmp
= BitmapFromBits(list_bits
, 16, 16, wxColour(128,128,128));
838 wxAuiSimpleTabArt
::~wxAuiSimpleTabArt()
842 wxAuiTabArt
* wxAuiSimpleTabArt
::Clone()
844 return static_cast<wxAuiTabArt
*>(new wxAuiSimpleTabArt
);
848 void wxAuiSimpleTabArt
::SetFlags(unsigned int flags
)
853 void wxAuiSimpleTabArt
::SetSizingInfo(const wxSize
& tab_ctrl_size
,
856 m_fixed_tab_width
= 100;
858 int tot_width
= (int)tab_ctrl_size
.x
- GetIndentSize() - 4;
860 if (m_flags
& wxAUI_NB_CLOSE_BUTTON
)
861 tot_width
-= m_active_close_bmp
.GetWidth();
862 if (m_flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
863 tot_width
-= m_active_windowlist_bmp
.GetWidth();
867 m_fixed_tab_width
= tot_width
/(int)tab_count
;
871 if (m_fixed_tab_width
< 100)
872 m_fixed_tab_width
= 100;
874 if (m_fixed_tab_width
> tot_width
/2)
875 m_fixed_tab_width
= tot_width
/2;
877 if (m_fixed_tab_width
> 220)
878 m_fixed_tab_width
= 220;
881 void wxAuiSimpleTabArt
::DrawBackground(wxDC
& dc
,
882 wxWindow
* WXUNUSED(wnd
),
886 dc
.SetBrush(m_bkbrush
);
887 dc
.SetPen(*wxTRANSPARENT_PEN
);
888 dc
.DrawRectangle(-1, -1, rect
.GetWidth()+2, rect
.GetHeight()+2);
891 dc
.SetPen(*wxGREY_PEN
);
892 dc
.DrawLine(0, rect
.GetHeight()-1, rect
.GetWidth(), rect
.GetHeight()-1);
896 // DrawTab() draws an individual tab.
899 // in_rect - rectangle the tab should be confined to
900 // caption - tab's caption
901 // active - whether or not the tab is active
902 // out_rect - actual output rectangle
903 // x_extent - the advance x; where the next tab should start
905 void wxAuiSimpleTabArt
::DrawTab(wxDC
& dc
,
907 const wxRect
& in_rect
,
908 const wxString
& caption_text
,
909 const wxBitmap
& bitmap
,
911 int close_button_state
,
912 wxRect
* out_tab_rect
,
913 wxRect
* out_button_rect
,
916 wxCoord normal_textx
, normal_texty
;
917 wxCoord selected_textx
, selected_texty
;
918 wxCoord textx
, texty
;
920 // if the caption is empty, measure some temporary text
921 wxString caption
= caption_text
;
922 if (caption_text
.empty())
925 dc
.SetFont(m_selected_font
);
926 dc
.GetTextExtent(caption
, &selected_textx
, &selected_texty
);
928 dc
.SetFont(m_normal_font
);
929 dc
.GetTextExtent(caption
, &normal_textx
, &normal_texty
);
931 // figure out the size of the tab
932 wxSize tab_size
= GetTabSize(dc
,
940 wxCoord tab_height
= tab_size
.y
;
941 wxCoord tab_width
= tab_size
.x
;
942 wxCoord tab_x
= in_rect
.x
;
943 wxCoord tab_y
= in_rect
.y
+ in_rect
.height
- tab_height
;
945 caption
= caption_text
;
947 // select pen, brush and font for the tab to be drawn
951 dc
.SetPen(m_selected_bkpen
);
952 dc
.SetBrush(m_selected_bkbrush
);
953 dc
.SetFont(m_selected_font
);
954 textx
= selected_textx
;
955 texty
= selected_texty
;
959 dc
.SetPen(m_normal_bkpen
);
960 dc
.SetBrush(m_normal_bkbrush
);
961 dc
.SetFont(m_normal_font
);
962 textx
= normal_textx
;
963 texty
= normal_texty
;
971 points
[0].y
= tab_y
+ tab_height
- 1;
972 points
[1].x
= tab_x
+ tab_height
- 3;
973 points
[1].y
= tab_y
+ 2;
974 points
[2].x
= tab_x
+ tab_height
+ 3;
976 points
[3].x
= tab_x
+ tab_width
- 2;
978 points
[4].x
= tab_x
+ tab_width
;
979 points
[4].y
= tab_y
+ 2;
980 points
[5].x
= tab_x
+ tab_width
;
981 points
[5].y
= tab_y
+ tab_height
- 1;
982 points
[6] = points
[0];
984 dc
.SetClippingRegion(in_rect
);
986 dc
.DrawPolygon(WXSIZEOF(points
) - 1, points
);
988 dc
.SetPen(*wxGREY_PEN
);
990 //dc.DrawLines(active ? WXSIZEOF(points) - 1 : WXSIZEOF(points), points);
991 dc
.DrawLines(WXSIZEOF(points
), points
);
996 int close_button_width
= 0;
997 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
999 close_button_width
= m_active_close_bmp
.GetWidth();
1000 text_offset
= tab_x
+ (tab_height
/2) + ((tab_width
-close_button_width
)/2) - (textx
/2);
1004 text_offset
= tab_x
+ (tab_height
/3) + (tab_width
/2) - (textx
/2);
1007 // set minimum text offset
1008 if (text_offset
< tab_x
+ tab_height
)
1009 text_offset
= tab_x
+ tab_height
;
1011 // chop text if necessary
1012 wxString draw_text
= ChopText(dc
,
1014 tab_width
- (text_offset
-tab_x
) - close_button_width
);
1017 dc
.DrawText(draw_text
,
1019 (tab_y
+ tab_height
)/2 - (texty
/2) + 1);
1022 // draw close button if necessary
1023 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1027 bmp
= m_active_close_bmp
;
1029 bmp
= m_disabled_close_bmp
;
1031 wxRect
rect(tab_x
+ tab_width
- close_button_width
- 1,
1032 tab_y
+ (tab_height
/2) - (bmp
.GetHeight()/2) + 1,
1035 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, close_button_state
);
1037 *out_button_rect
= rect
;
1041 *out_tab_rect
= wxRect(tab_x
, tab_y
, tab_width
, tab_height
);
1043 dc
.DestroyClippingRegion();
1046 int wxAuiSimpleTabArt
::GetIndentSize()
1051 wxSize wxAuiSimpleTabArt
::GetTabSize(wxDC
& dc
,
1052 wxWindow
* WXUNUSED(wnd
),
1053 const wxString
& caption
,
1054 const wxBitmap
& WXUNUSED(bitmap
),
1055 bool WXUNUSED(active
),
1056 int close_button_state
,
1059 wxCoord measured_textx
, measured_texty
;
1061 dc
.SetFont(m_measuring_font
);
1062 dc
.GetTextExtent(caption
, &measured_textx
, &measured_texty
);
1064 wxCoord tab_height
= measured_texty
+ 4;
1065 wxCoord tab_width
= measured_textx
+ tab_height
+ 5;
1067 if (close_button_state
!= wxAUI_BUTTON_STATE_HIDDEN
)
1068 tab_width
+= m_active_close_bmp
.GetWidth();
1070 if (m_flags
& wxAUI_NB_TAB_FIXED_WIDTH
)
1072 tab_width
= m_fixed_tab_width
;
1075 *x_extent
= tab_width
- (tab_height
/2) - 1;
1077 return wxSize(tab_width
, tab_height
);
1081 void wxAuiSimpleTabArt
::DrawButton(wxDC
& dc
,
1082 wxWindow
* WXUNUSED(wnd
),
1083 const wxRect
& in_rect
,
1087 const wxBitmap
& bitmap_override
,
1093 if (bitmap_override
.IsOk())
1095 bmp
= bitmap_override
;
1101 case wxAUI_BUTTON_CLOSE
:
1102 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1103 bmp
= m_disabled_close_bmp
;
1105 bmp
= m_active_close_bmp
;
1107 case wxAUI_BUTTON_LEFT
:
1108 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1109 bmp
= m_disabled_left_bmp
;
1111 bmp
= m_active_left_bmp
;
1113 case wxAUI_BUTTON_RIGHT
:
1114 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1115 bmp
= m_disabled_right_bmp
;
1117 bmp
= m_active_right_bmp
;
1119 case wxAUI_BUTTON_WINDOWLIST
:
1120 if (button_state
& wxAUI_BUTTON_STATE_DISABLED
)
1121 bmp
= m_disabled_windowlist_bmp
;
1123 bmp
= m_active_windowlist_bmp
;
1133 if (orientation
== wxLEFT
)
1135 rect
.SetX(in_rect
.x
);
1136 rect
.SetY(((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2));
1137 rect
.SetWidth(bmp
.GetWidth());
1138 rect
.SetHeight(bmp
.GetHeight());
1142 rect
= wxRect(in_rect
.x
+ in_rect
.width
- bmp
.GetWidth(),
1143 ((in_rect
.y
+ in_rect
.height
)/2) - (bmp
.GetHeight()/2),
1144 bmp
.GetWidth(), bmp
.GetHeight());
1148 DrawButtons(dc
, rect
, bmp
, *wxWHITE
, button_state
);
1154 int wxAuiSimpleTabArt
::ShowWindowList(wxWindow
* wnd
,
1155 const wxArrayString
& items
,
1160 size_t i
, count
= items
.GetCount();
1161 for (i
= 0; i
< count
; ++i
)
1163 menuPopup
.AppendCheckItem(1000+i
, items
.Item(i
));
1166 if (active_idx
!= -1)
1168 menuPopup
.Check(1000+active_idx
, true);
1171 // find out where to put the popup menu of window
1172 // items. Subtract 100 for now to center the menu
1173 // a bit, until a better mechanism can be implemented
1174 wxPoint pt
= ::wxGetMousePosition();
1175 pt
= wnd
->ScreenToClient(pt
);
1181 // find out the screen coordinate at the bottom of the tab ctrl
1182 wxRect cli_rect
= wnd
->GetClientRect();
1183 pt
.y
= cli_rect
.y
+ cli_rect
.height
;
1185 wxAuiCommandCapture
* cc
= new wxAuiCommandCapture
;
1186 wnd
->PushEventHandler(cc
);
1187 wnd
->PopupMenu(&menuPopup
, pt
);
1188 int command
= cc
->GetCommandId();
1189 wnd
->PopEventHandler(true);
1191 if (command
>= 1000)
1192 return command
-1000;
1197 int wxAuiSimpleTabArt
::GetBestTabCtrlSize(wxWindow
* wnd
,
1198 wxAuiNotebookPageArray
& WXUNUSED(pages
),
1199 const wxSize
& WXUNUSED(required_bmp_size
))
1202 dc
.SetFont(m_measuring_font
);
1204 wxSize s
= GetTabSize(dc
,
1209 wxAUI_BUTTON_STATE_HIDDEN
,
1214 void wxAuiSimpleTabArt
::SetNormalFont(const wxFont
& font
)
1216 m_normal_font
= font
;
1219 void wxAuiSimpleTabArt
::SetSelectedFont(const wxFont
& font
)
1221 m_selected_font
= font
;
1224 void wxAuiSimpleTabArt
::SetMeasuringFont(const wxFont
& font
)
1226 m_measuring_font
= font
;
1232 // -- wxAuiTabContainer class implementation --
1235 // wxAuiTabContainer is a class which contains information about each
1236 // tab. It also can render an entire tab control to a specified DC.
1237 // It's not a window class itself, because this code will be used by
1238 // the wxFrameMananger, where it is disadvantageous to have separate
1239 // windows for each tab control in the case of "docked tabs"
1241 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window
1242 // which can be used as a tab control in the normal sense.
1245 wxAuiTabContainer
::wxAuiTabContainer()
1249 m_art
= new wxAuiDefaultTabArt
;
1251 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
1252 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
1253 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
1254 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
1257 wxAuiTabContainer
::~wxAuiTabContainer()
1262 void wxAuiTabContainer
::SetArtProvider(wxAuiTabArt
* art
)
1269 m_art
->SetFlags(m_flags
);
1273 wxAuiTabArt
* wxAuiTabContainer
::GetArtProvider() const
1278 void wxAuiTabContainer
::SetFlags(unsigned int flags
)
1282 // check for new close button settings
1283 RemoveButton(wxAUI_BUTTON_LEFT
);
1284 RemoveButton(wxAUI_BUTTON_RIGHT
);
1285 RemoveButton(wxAUI_BUTTON_WINDOWLIST
);
1286 RemoveButton(wxAUI_BUTTON_CLOSE
);
1289 if (flags
& wxAUI_NB_SCROLL_BUTTONS
)
1291 AddButton(wxAUI_BUTTON_LEFT
, wxLEFT
);
1292 AddButton(wxAUI_BUTTON_RIGHT
, wxRIGHT
);
1295 if (flags
& wxAUI_NB_WINDOWLIST_BUTTON
)
1297 AddButton(wxAUI_BUTTON_WINDOWLIST
, wxRIGHT
);
1300 if (flags
& wxAUI_NB_CLOSE_BUTTON
)
1302 AddButton(wxAUI_BUTTON_CLOSE
, wxRIGHT
);
1307 m_art
->SetFlags(m_flags
);
1311 unsigned int wxAuiTabContainer
::GetFlags() const
1317 void wxAuiTabContainer
::SetNormalFont(const wxFont
& font
)
1319 m_art
->SetNormalFont(font
);
1322 void wxAuiTabContainer
::SetSelectedFont(const wxFont
& font
)
1324 m_art
->SetSelectedFont(font
);
1327 void wxAuiTabContainer
::SetMeasuringFont(const wxFont
& font
)
1329 m_art
->SetMeasuringFont(font
);
1332 void wxAuiTabContainer
::SetRect(const wxRect
& rect
)
1338 m_art
->SetSizingInfo(rect
.GetSize(), m_pages
.GetCount());
1342 bool wxAuiTabContainer
::AddPage(wxWindow
* page
,
1343 const wxAuiNotebookPage
& info
)
1345 wxAuiNotebookPage page_info
;
1347 page_info
.window
= page
;
1349 m_pages
.Add(page_info
);
1351 // let the art provider know how many pages we have
1354 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1360 bool wxAuiTabContainer
::InsertPage(wxWindow
* page
,
1361 const wxAuiNotebookPage
& info
,
1364 wxAuiNotebookPage page_info
;
1366 page_info
.window
= page
;
1368 if (idx
>= m_pages
.GetCount())
1369 m_pages
.Add(page_info
);
1371 m_pages
.Insert(page_info
, idx
);
1373 // let the art provider know how many pages we have
1376 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1382 bool wxAuiTabContainer
::MovePage(wxWindow
* page
,
1385 int idx
= GetIdxFromWindow(page
);
1389 // get page entry, make a copy of it
1390 wxAuiNotebookPage p
= GetPage(idx
);
1392 // remove old page entry
1395 // insert page where it should be
1396 InsertPage(page
, p
, new_idx
);
1401 bool wxAuiTabContainer
::RemovePage(wxWindow
* wnd
)
1403 size_t i
, page_count
= m_pages
.GetCount();
1404 for (i
= 0; i
< page_count
; ++i
)
1406 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1407 if (page
.window
== wnd
)
1409 m_pages
.RemoveAt(i
);
1411 // let the art provider know how many pages we have
1414 m_art
->SetSizingInfo(m_rect
.GetSize(), m_pages
.GetCount());
1424 bool wxAuiTabContainer
::SetActivePage(wxWindow
* wnd
)
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 if (page
.window
== wnd
)
1439 page
.active
= false;
1446 void wxAuiTabContainer
::SetNoneActive()
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 page
.active
= false;
1456 bool wxAuiTabContainer
::SetActivePage(size_t page
)
1458 if (page
>= m_pages
.GetCount())
1461 return SetActivePage(m_pages
.Item(page
).window
);
1464 int wxAuiTabContainer
::GetActivePage() const
1466 size_t i
, page_count
= m_pages
.GetCount();
1467 for (i
= 0; i
< page_count
; ++i
)
1469 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1477 wxWindow
* wxAuiTabContainer
::GetWindowFromIdx(size_t idx
) const
1479 if (idx
>= m_pages
.GetCount())
1482 return m_pages
[idx
].window
;
1485 int wxAuiTabContainer
::GetIdxFromWindow(wxWindow
* wnd
) const
1487 size_t i
, page_count
= m_pages
.GetCount();
1488 for (i
= 0; i
< page_count
; ++i
)
1490 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1491 if (page
.window
== wnd
)
1497 wxAuiNotebookPage
& wxAuiTabContainer
::GetPage(size_t idx
)
1499 wxASSERT_MSG(idx
< m_pages
.GetCount(), wxT("Invalid Page index"));
1501 return m_pages
[idx
];
1504 wxAuiNotebookPageArray
& wxAuiTabContainer
::GetPages()
1509 size_t wxAuiTabContainer
::GetPageCount() const
1511 return m_pages
.GetCount();
1514 void wxAuiTabContainer
::AddButton(int id
,
1516 const wxBitmap
& normal_bitmap
,
1517 const wxBitmap
& disabled_bitmap
)
1519 wxAuiTabContainerButton button
;
1521 button
.bitmap
= normal_bitmap
;
1522 button
.dis_bitmap
= disabled_bitmap
;
1523 button
.location
= location
;
1524 button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1526 m_buttons
.Add(button
);
1529 void wxAuiTabContainer
::RemoveButton(int id
)
1531 size_t i
, button_count
= m_buttons
.GetCount();
1533 for (i
= 0; i
< button_count
; ++i
)
1535 if (m_buttons
.Item(i
).id
== id
)
1537 m_buttons
.RemoveAt(i
);
1545 size_t wxAuiTabContainer
::GetTabOffset() const
1547 return m_tab_offset
;
1550 void wxAuiTabContainer
::SetTabOffset(size_t offset
)
1552 m_tab_offset
= offset
;
1558 // Render() renders the tab catalog to the specified DC
1559 // It is a virtual function and can be overridden to
1560 // provide custom drawing capabilities
1561 void wxAuiTabContainer
::Render(wxDC
* raw_dc
, wxWindow
* wnd
)
1563 if (!raw_dc
|| !raw_dc
->IsOk())
1569 size_t page_count
= m_pages
.GetCount();
1570 size_t button_count
= m_buttons
.GetCount();
1572 // create off-screen bitmap
1573 bmp
.Create(m_rect
.GetWidth(), m_rect
.GetHeight());
1574 dc
.SelectObject(bmp
);
1579 // find out if size of tabs is larger than can be
1580 // afforded on screen
1581 int total_width
= 0;
1582 int visible_width
= 0;
1583 for (i
= 0; i
< page_count
; ++i
)
1585 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1587 // determine if a close button is on this tab
1588 bool close_button
= false;
1589 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1590 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1592 close_button
= true;
1597 wxSize size
= m_art
->GetTabSize(dc
,
1603 wxAUI_BUTTON_STATE_NORMAL
:
1604 wxAUI_BUTTON_STATE_HIDDEN
,
1607 if (i
+1 < page_count
)
1608 total_width
+= x_extent
;
1610 total_width
+= size
.x
;
1612 if (i
>= m_tab_offset
)
1614 if (i
+1 < page_count
)
1615 visible_width
+= x_extent
;
1617 visible_width
+= size
.x
;
1621 if (total_width
> m_rect
.GetWidth() || m_tab_offset
!= 0)
1623 // show left/right buttons
1624 for (i
= 0; i
< button_count
; ++i
)
1626 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1627 if (button
.id
== wxAUI_BUTTON_LEFT
||
1628 button
.id
== wxAUI_BUTTON_RIGHT
)
1630 button
.cur_state
&= ~wxAUI_BUTTON_STATE_HIDDEN
;
1636 // hide left/right buttons
1637 for (i
= 0; i
< button_count
; ++i
)
1639 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1640 if (button
.id
== wxAUI_BUTTON_LEFT
||
1641 button
.id
== wxAUI_BUTTON_RIGHT
)
1643 button
.cur_state
|= wxAUI_BUTTON_STATE_HIDDEN
;
1648 // determine whether left button should be enabled
1649 for (i
= 0; i
< button_count
; ++i
)
1651 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1652 if (button
.id
== wxAUI_BUTTON_LEFT
)
1654 if (m_tab_offset
== 0)
1655 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
1657 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
1659 if (button
.id
== wxAUI_BUTTON_RIGHT
)
1661 if (visible_width
< m_rect
.GetWidth() - ((int)button_count
*16))
1662 button
.cur_state
|= wxAUI_BUTTON_STATE_DISABLED
;
1664 button
.cur_state
&= ~wxAUI_BUTTON_STATE_DISABLED
;
1671 m_art
->DrawBackground(dc
, wnd
, m_rect
);
1674 int left_buttons_width
= 0;
1675 int right_buttons_width
= 0;
1679 // draw the buttons on the right side
1680 offset
= m_rect
.x
+ m_rect
.width
;
1681 for (i
= 0; i
< button_count
; ++i
)
1683 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
1685 if (button
.location
!= wxRIGHT
)
1687 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
1690 wxRect button_rect
= m_rect
;
1691 button_rect
.SetY(1);
1692 button_rect
.SetWidth(offset
);
1694 m_art
->DrawButton(dc
,
1703 offset
-= button
.rect
.GetWidth();
1704 right_buttons_width
+= button
.rect
.GetWidth();
1711 // draw the buttons on the left side
1713 for (i
= 0; i
< button_count
; ++i
)
1715 wxAuiTabContainerButton
& button
= m_buttons
.Item(button_count
- i
- 1);
1717 if (button
.location
!= wxLEFT
)
1719 if (button
.cur_state
& wxAUI_BUTTON_STATE_HIDDEN
)
1722 wxRect
button_rect(offset
, 1, 1000, m_rect
.height
);
1724 m_art
->DrawButton(dc
,
1733 offset
+= button
.rect
.GetWidth();
1734 left_buttons_width
+= button
.rect
.GetWidth();
1737 offset
= left_buttons_width
;
1740 offset
+= m_art
->GetIndentSize();
1743 // prepare the tab-close-button array
1744 // make sure tab button entries which aren't used are marked as hidden
1745 for (i
= page_count
; i
< m_tab_close_buttons
.GetCount(); ++i
)
1746 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1748 // make sure there are enough tab button entries to accommodate all tabs
1749 while (m_tab_close_buttons
.GetCount() < page_count
)
1751 wxAuiTabContainerButton tempbtn
;
1752 tempbtn
.id
= wxAUI_BUTTON_CLOSE
;
1753 tempbtn
.location
= wxCENTER
;
1754 tempbtn
.cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1755 m_tab_close_buttons
.Add(tempbtn
);
1759 // buttons before the tab offset must be set to hidden
1760 for (i
= 0; i
< m_tab_offset
; ++i
)
1762 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1768 size_t active
= 999;
1769 int active_offset
= 0;
1773 wxRect rect
= m_rect
;
1775 rect
.height
= m_rect
.height
;
1777 for (i
= m_tab_offset
; i
< page_count
; ++i
)
1779 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1780 wxAuiTabContainerButton
& tab_button
= m_tab_close_buttons
.Item(i
);
1782 // determine if a close button is on this tab
1783 bool close_button
= false;
1784 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1785 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1787 close_button
= true;
1788 if (tab_button
.cur_state
== wxAUI_BUTTON_STATE_HIDDEN
)
1790 tab_button
.id
= wxAUI_BUTTON_CLOSE
;
1791 tab_button
.cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
1792 tab_button
.location
= wxCENTER
;
1797 tab_button
.cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1801 rect
.width
= m_rect
.width
- right_buttons_width
- offset
- 2;
1803 if (rect
.width
<= 0)
1812 tab_button
.cur_state
,
1820 active_offset
= offset
;
1828 // make sure to deactivate buttons which are off the screen to the right
1829 for (++i
; i
< m_tab_close_buttons
.GetCount(); ++i
)
1831 m_tab_close_buttons
.Item(i
).cur_state
= wxAUI_BUTTON_STATE_HIDDEN
;
1835 // draw the active tab again so it stands in the foreground
1836 if (active
>= m_tab_offset
&& active
< m_pages
.GetCount())
1838 wxAuiNotebookPage
& page
= m_pages
.Item(active
);
1840 wxAuiTabContainerButton
& tab_button
= m_tab_close_buttons
.Item(active
);
1842 // determine if a close button is on this tab
1843 bool close_button
= false;
1844 if ((m_flags
& wxAUI_NB_CLOSE_ON_ALL_TABS
) != 0 ||
1845 ((m_flags
& wxAUI_NB_CLOSE_ON_ACTIVE_TAB
) != 0 && page
.active
))
1847 close_button
= true;
1850 rect
.x
= active_offset
;
1857 tab_button
.cur_state
,
1864 raw_dc
->Blit(m_rect
.x
, m_rect
.y
,
1865 m_rect
.GetWidth(), m_rect
.GetHeight(),
1870 // TabHitTest() tests if a tab was hit, passing the window pointer
1871 // back if that condition was fulfilled. The function returns
1872 // true if a tab was hit, otherwise false
1873 bool wxAuiTabContainer
::TabHitTest(int x
, int y
, wxWindow
** hit
) const
1875 if (!m_rect
.Contains(x
,y
))
1878 wxAuiTabContainerButton
* btn
= NULL
;
1879 if (ButtonHitTest(x
, y
, &btn
))
1881 if (m_buttons
.Index(*btn
) != wxNOT_FOUND
)
1885 size_t i
, page_count
= m_pages
.GetCount();
1887 for (i
= m_tab_offset
; i
< page_count
; ++i
)
1889 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
1890 if (page
.rect
.Contains(x
,y
))
1901 // ButtonHitTest() tests if a button was hit. The function returns
1902 // true if a button was hit, otherwise false
1903 bool wxAuiTabContainer
::ButtonHitTest(int x
, int y
,
1904 wxAuiTabContainerButton
** hit
) const
1906 if (!m_rect
.Contains(x
,y
))
1909 size_t i
, button_count
;
1912 button_count
= m_buttons
.GetCount();
1913 for (i
= 0; i
< button_count
; ++i
)
1915 wxAuiTabContainerButton
& button
= m_buttons
.Item(i
);
1916 if (button
.rect
.Contains(x
,y
) &&
1917 !(button
.cur_state
& (wxAUI_BUTTON_STATE_HIDDEN
|
1918 wxAUI_BUTTON_STATE_DISABLED
)))
1926 button_count
= m_tab_close_buttons
.GetCount();
1927 for (i
= 0; i
< button_count
; ++i
)
1929 wxAuiTabContainerButton
& button
= m_tab_close_buttons
.Item(i
);
1930 if (button
.rect
.Contains(x
,y
) &&
1931 !(button
.cur_state
& (wxAUI_BUTTON_STATE_HIDDEN
|
1932 wxAUI_BUTTON_STATE_DISABLED
)))
1945 // the utility function ShowWnd() is the same as show,
1946 // except it handles wxAuiMDIChildFrame windows as well,
1947 // as the Show() method on this class is "unplugged"
1948 static void ShowWnd(wxWindow
* wnd
, bool show
)
1950 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
1952 wxAuiMDIChildFrame
* cf
= (wxAuiMDIChildFrame
*)wnd
;
1962 // DoShowHide() this function shows the active window, then
1963 // hides all of the other windows (in that order)
1964 void wxAuiTabContainer
::DoShowHide()
1966 wxAuiNotebookPageArray
& pages
= GetPages();
1967 size_t i
, page_count
= pages
.GetCount();
1969 // show new active page first
1970 for (i
= 0; i
< page_count
; ++i
)
1972 wxAuiNotebookPage
& page
= pages
.Item(i
);
1975 ShowWnd(page
.window
, true);
1980 // hide all other pages
1981 for (i
= 0; i
< page_count
; ++i
)
1983 wxAuiNotebookPage
& page
= pages
.Item(i
);
1984 ShowWnd(page
.window
, page
.active
);
1993 // -- wxAuiTabCtrl class implementation --
1997 BEGIN_EVENT_TABLE(wxAuiTabCtrl
, wxControl
)
1998 EVT_PAINT(wxAuiTabCtrl
::OnPaint
)
1999 EVT_ERASE_BACKGROUND(wxAuiTabCtrl
::OnEraseBackground
)
2000 EVT_SIZE(wxAuiTabCtrl
::OnSize
)
2001 EVT_LEFT_DOWN(wxAuiTabCtrl
::OnLeftDown
)
2002 EVT_LEFT_UP(wxAuiTabCtrl
::OnLeftUp
)
2003 EVT_MOTION(wxAuiTabCtrl
::OnMotion
)
2004 EVT_LEAVE_WINDOW(wxAuiTabCtrl
::OnLeaveWindow
)
2005 EVT_AUINOTEBOOK_BUTTON(-1, wxAuiTabCtrl
::OnButton
)
2009 wxAuiTabCtrl
::wxAuiTabCtrl(wxWindow
* parent
,
2013 long style
) : wxControl(parent
, id
, pos
, size
, style
)
2015 m_click_pt
= wxDefaultPosition
;
2016 m_is_dragging
= false;
2017 m_hover_button
= NULL
;
2018 m_pressed_button
= NULL
;
2021 wxAuiTabCtrl
::~wxAuiTabCtrl()
2025 void wxAuiTabCtrl
::OnPaint(wxPaintEvent
&)
2029 dc
.SetFont(GetFont());
2031 if (GetPageCount() > 0)
2035 void wxAuiTabCtrl
::OnEraseBackground(wxEraseEvent
& WXUNUSED(evt
))
2039 void wxAuiTabCtrl
::OnSize(wxSizeEvent
& evt
)
2041 wxSize s
= evt
.GetSize();
2042 wxRect
r(0, 0, s
.GetWidth(), s
.GetHeight());
2046 void wxAuiTabCtrl
::OnLeftDown(wxMouseEvent
& evt
)
2049 m_click_pt
= wxDefaultPosition
;
2050 m_is_dragging
= false;
2052 m_pressed_button
= NULL
;
2056 if (TabHitTest(evt
.m_x
, evt
.m_y
, &wnd
))
2058 int new_selection
= GetIdxFromWindow(wnd
);
2060 if (new_selection
!= GetActivePage())
2062 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2063 e
.SetSelection(new_selection
);
2064 e
.SetOldSelection(GetActivePage());
2065 e
.SetEventObject(this);
2066 GetEventHandler()->ProcessEvent(e
);
2069 m_click_pt
.x
= evt
.m_x
;
2070 m_click_pt
.y
= evt
.m_y
;
2076 m_pressed_button
= m_hover_button
;
2077 m_pressed_button
->cur_state
= wxAUI_BUTTON_STATE_PRESSED
;
2083 void wxAuiTabCtrl
::OnLeftUp(wxMouseEvent
& evt
)
2085 if (GetCapture() == this)
2090 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
, m_windowId
);
2091 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2092 evt
.SetOldSelection(evt
.GetSelection());
2093 evt
.SetEventObject(this);
2094 GetEventHandler()->ProcessEvent(evt
);
2098 if (m_pressed_button
)
2100 // make sure we're still clicking the button
2101 wxAuiTabContainerButton
* button
= NULL
;
2102 if (!ButtonHitTest(evt
.m_x
, evt
.m_y
, &button
))
2105 if (button
!= m_pressed_button
)
2107 m_pressed_button
= NULL
;
2114 if (!(m_pressed_button
->cur_state
& wxAUI_BUTTON_STATE_DISABLED
))
2116 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON
, m_windowId
);
2117 evt
.SetInt(m_pressed_button
->id
);
2118 evt
.SetEventObject(this);
2119 GetEventHandler()->ProcessEvent(evt
);
2122 m_pressed_button
= NULL
;
2125 m_click_pt
= wxDefaultPosition
;
2126 m_is_dragging
= false;
2130 void wxAuiTabCtrl
::OnMotion(wxMouseEvent
& evt
)
2132 wxPoint pos
= evt
.GetPosition();
2134 // check if the mouse is hovering above a button
2135 wxAuiTabContainerButton
* button
;
2136 if (ButtonHitTest(pos
.x
, pos
.y
, &button
))
2138 if (m_hover_button
&& button
!= m_hover_button
)
2140 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2141 m_hover_button
= NULL
;
2146 if (button
->cur_state
!= wxAUI_BUTTON_STATE_HOVER
)
2148 button
->cur_state
= wxAUI_BUTTON_STATE_HOVER
;
2151 m_hover_button
= button
;
2159 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2160 m_hover_button
= NULL
;
2167 if (!evt
.LeftIsDown() || m_click_pt
== wxDefaultPosition
)
2172 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
, m_windowId
);
2173 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2174 evt
.SetOldSelection(evt
.GetSelection());
2175 evt
.SetEventObject(this);
2176 GetEventHandler()->ProcessEvent(evt
);
2181 int drag_x_threshold
= wxSystemSettings
::GetMetric(wxSYS_DRAG_X
);
2182 int drag_y_threshold
= wxSystemSettings
::GetMetric(wxSYS_DRAG_Y
);
2184 if (abs(pos
.x
- m_click_pt
.x
) > drag_x_threshold
||
2185 abs(pos
.y
- m_click_pt
.y
) > drag_y_threshold
)
2187 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
, m_windowId
);
2188 evt
.SetSelection(GetIdxFromWindow(m_click_tab
));
2189 evt
.SetOldSelection(evt
.GetSelection());
2190 evt
.SetEventObject(this);
2191 GetEventHandler()->ProcessEvent(evt
);
2193 m_is_dragging
= true;
2197 void wxAuiTabCtrl
::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
))
2201 m_hover_button
->cur_state
= wxAUI_BUTTON_STATE_NORMAL
;
2202 m_hover_button
= NULL
;
2208 void wxAuiTabCtrl
::OnButton(wxAuiNotebookEvent
& event
)
2210 int button
= event
.GetInt();
2212 if (button
== wxAUI_BUTTON_LEFT
|| button
== wxAUI_BUTTON_RIGHT
)
2214 if (button
== wxAUI_BUTTON_LEFT
)
2216 if (GetTabOffset() > 0)
2218 SetTabOffset(GetTabOffset()-1);
2225 SetTabOffset(GetTabOffset()+1);
2230 else if (button
== wxAUI_BUTTON_WINDOWLIST
)
2234 size_t i
, page_count
= m_pages
.GetCount();
2235 for (i
= 0; i
< page_count
; ++i
)
2237 wxAuiNotebookPage
& page
= m_pages
.Item(i
);
2238 as
.Add(page
.caption
);
2241 int idx
= GetArtProvider()->ShowWindowList(this, as
, GetActivePage());
2245 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2246 e
.SetSelection(idx
);
2247 e
.SetOldSelection(GetActivePage());
2248 e
.SetEventObject(this);
2249 GetEventHandler()->ProcessEvent(e
);
2258 // wxTabFrame is an interesting case. It's important that all child pages
2259 // of the multi-notebook control are all actually children of that control
2260 // (and not grandchildren). wxTabFrame facilitates this. There is one
2261 // instance of wxTabFrame for each tab control inside the multi-notebook.
2262 // It's important to know that wxTabFrame is not a real window, but it merely
2263 // used to capture the dimensions/positioning of the internal tab control and
2264 // it's managed page windows
2266 class wxTabFrame
: public wxWindow
2273 m_rect
= wxRect(0,0,200,200);
2274 m_tab_ctrl_height
= 20;
2277 void SetTabCtrlHeight(int h
)
2279 m_tab_ctrl_height
= h
;
2282 void DoSetSize(int x
, int y
,
2283 int width
, int height
,
2284 int WXUNUSED(sizeFlags
= wxSIZE_AUTO
))
2286 m_rect
= wxRect(x
, y
, width
, height
);
2290 void DoGetClientSize(int* x
, int* y
) const
2296 bool Show( bool WXUNUSED(show
= true) ) { return false; }
2303 m_tab_rect
= wxRect(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
);
2304 m_tabs
->SetSize(m_rect
.x
, m_rect
.y
, m_rect
.width
, m_tab_ctrl_height
);
2305 m_tabs
->SetRect(wxRect(0, 0, m_rect
.width
, m_tab_ctrl_height
));
2309 wxAuiNotebookPageArray
& pages
= m_tabs
->GetPages();
2310 size_t i
, page_count
= pages
.GetCount();
2312 for (i
= 0; i
< page_count
; ++i
)
2314 wxAuiNotebookPage
& page
= pages
.Item(i
);
2315 page
.window
->SetSize(m_rect
.x
, m_rect
.y
+ m_tab_ctrl_height
,
2316 m_rect
.width
, m_rect
.height
- m_tab_ctrl_height
);
2318 if (page
.window
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
2320 wxAuiMDIChildFrame
* wnd
= (wxAuiMDIChildFrame
*)page
.window
;
2321 wnd
->ApplyMDIChildFrameRect();
2326 void DoGetSize(int* x
, int* y
) const
2329 *x
= m_rect
.GetWidth();
2331 *y
= m_rect
.GetHeight();
2343 wxAuiTabCtrl
* m_tabs
;
2344 int m_tab_ctrl_height
;
2351 // -- wxAuiNotebook class implementation --
2353 BEGIN_EVENT_TABLE(wxAuiNotebook
, wxControl
)
2354 //EVT_ERASE_BACKGROUND(wxAuiNotebook::OnEraseBackground)
2355 EVT_SIZE(wxAuiNotebook
::OnSize
)
2356 //EVT_LEFT_DOWN(wxAuiNotebook::OnLeftDown)
2357 EVT_CHILD_FOCUS(wxAuiNotebook
::OnChildFocus
)
2358 EVT_COMMAND_RANGE(10000, 10100,
2359 wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
,
2360 wxAuiNotebook
::OnTabClicked
)
2361 EVT_COMMAND_RANGE(10000, 10100,
2362 wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG
,
2363 wxAuiNotebook
::OnTabBeginDrag
)
2364 EVT_COMMAND_RANGE(10000, 10100,
2365 wxEVT_COMMAND_AUINOTEBOOK_END_DRAG
,
2366 wxAuiNotebook
::OnTabEndDrag
)
2367 EVT_COMMAND_RANGE(10000, 10100,
2368 wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION
,
2369 wxAuiNotebook
::OnTabDragMotion
)
2370 EVT_COMMAND_RANGE(10000, 10100,
2371 wxEVT_COMMAND_AUINOTEBOOK_BUTTON
,
2372 wxAuiNotebook
::OnTabButton
)
2375 wxAuiNotebook
::wxAuiNotebook()
2378 m_tab_id_counter
= 10000;
2380 m_tab_ctrl_height
= 20;
2381 m_requested_bmp_size
= wxDefaultSize
;
2382 m_requested_tabctrl_height
= -1;
2385 wxAuiNotebook
::wxAuiNotebook(wxWindow
*parent
,
2389 long style
) : wxControl(parent
, id
, pos
, size
, style
)
2392 m_requested_bmp_size
= wxDefaultSize
;
2393 m_requested_tabctrl_height
= -1;
2394 InitNotebook(style
);
2397 bool wxAuiNotebook
::Create(wxWindow
* parent
,
2403 if (!wxControl
::Create(parent
, id
, pos
, size
, style
))
2406 InitNotebook(style
);
2411 // InitNotebook() contains common initialization
2412 // code called by all constructors
2413 void wxAuiNotebook
::InitNotebook(long style
)
2416 m_tab_id_counter
= 10000;
2418 m_flags
= (unsigned int)style
;
2419 m_tab_ctrl_height
= 20;
2421 m_normal_font
= *wxNORMAL_FONT
;
2422 m_selected_font
= *wxNORMAL_FONT
;
2423 m_selected_font
.SetWeight(wxBOLD
);
2425 SetArtProvider(new wxAuiDefaultTabArt
);
2427 m_dummy_wnd
= new wxWindow(this, wxID_ANY
, wxPoint(0,0), wxSize(0,0));
2428 m_dummy_wnd
->SetSize(200, 200);
2429 m_dummy_wnd
->Show(false);
2431 m_mgr
.SetManagedWindow(this);
2432 m_mgr
.SetFlags(wxAUI_MGR_DEFAULT
| (1 << 28) /*wxAUI_MGR_NO_DOCK_SIZE_LIMIT*/);
2434 m_mgr
.AddPane(m_dummy_wnd
,
2435 wxAuiPaneInfo().Name(wxT("dummy")).Bottom().CaptionVisible(false).Show(false));
2440 wxAuiNotebook
::~wxAuiNotebook()
2445 void wxAuiNotebook
::SetArtProvider(wxAuiTabArt
* art
)
2447 m_tabs
.SetArtProvider(art
);
2449 UpdateTabCtrlHeight();
2452 // SetTabCtrlHeight() is the highest-level override of the
2453 // tab height. A call to this function effectively enforces a
2454 // specified tab ctrl height, overriding all other considerations,
2455 // such as text or bitmap height. It overrides any call to
2456 // SetUniformBitmapSize(). Specifying a height of -1 reverts
2457 // any previous call and returns to the default behavior
2459 void wxAuiNotebook
::SetTabCtrlHeight(int height
)
2461 m_requested_tabctrl_height
= height
;
2463 // if window is already initialized, recalculate the tab height
2466 UpdateTabCtrlHeight();
2471 // SetUniformBitmapSize() ensures that all tabs will have
2472 // the same height, even if some tabs don't have bitmaps
2473 // Passing wxDefaultSize to this function will instruct
2474 // the control to use dynamic tab height-- so when a tab
2475 // with a large bitmap is added, the tab ctrl's height will
2476 // automatically increase to accommodate the bitmap
2478 void wxAuiNotebook
::SetUniformBitmapSize(const wxSize
& size
)
2480 m_requested_bmp_size
= size
;
2482 // if window is already initialized, recalculate the tab height
2485 UpdateTabCtrlHeight();
2489 // UpdateTabCtrlHeight() does the actual tab resizing. It's meant
2490 // to be used interally
2491 void wxAuiNotebook
::UpdateTabCtrlHeight()
2493 // get the tab ctrl height we will use
2494 int height
= CalculateTabCtrlHeight();
2496 // if the tab control height needs to change, update
2497 // all of our tab controls with the new height
2498 if (m_tab_ctrl_height
!= height
)
2500 wxAuiTabArt
* art
= m_tabs
.GetArtProvider();
2502 m_tab_ctrl_height
= height
;
2504 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2505 size_t i
, pane_count
= all_panes
.GetCount();
2506 for (i
= 0; i
< pane_count
; ++i
)
2508 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2509 if (pane
.name
== wxT("dummy"))
2511 wxTabFrame
* tab_frame
= (wxTabFrame
*)pane
.window
;
2512 wxAuiTabCtrl
* tabctrl
= tab_frame
->m_tabs
;
2513 tab_frame
->SetTabCtrlHeight(m_tab_ctrl_height
);
2514 tabctrl
->SetArtProvider(art
->Clone());
2515 tab_frame
->DoSizing();
2520 void wxAuiNotebook
::UpdateHintWindowSize()
2522 wxSize size
= CalculateNewSplitSize();
2524 // the placeholder hint window should be set to this size
2525 wxAuiPaneInfo
& info
= m_mgr
.GetPane(wxT("dummy"));
2529 info
.BestSize(size
);
2530 m_dummy_wnd
->SetSize(size
);
2535 // calculates the size of the new split
2536 wxSize wxAuiNotebook
::CalculateNewSplitSize()
2538 // count number of tab controls
2539 int tab_ctrl_count
= 0;
2540 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2541 size_t i
, pane_count
= all_panes
.GetCount();
2542 for (i
= 0; i
< pane_count
; ++i
)
2544 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2545 if (pane
.name
== wxT("dummy"))
2550 wxSize new_split_size
;
2552 // if there is only one tab control, the first split
2553 // should happen around the middle
2554 if (tab_ctrl_count
< 2)
2556 new_split_size
= GetClientSize();
2557 new_split_size
.x
/= 2;
2558 new_split_size
.y
/= 2;
2562 // this is in place of a more complicated calculation
2563 // that needs to be implemented
2564 new_split_size
= wxSize(180,180);
2567 return new_split_size
;
2570 int wxAuiNotebook
::CalculateTabCtrlHeight()
2572 // if a fixed tab ctrl height is specified,
2573 // just return that instead of calculating a
2575 if (m_requested_tabctrl_height
!= -1)
2576 return m_requested_tabctrl_height
;
2578 // find out new best tab height
2579 wxAuiTabArt
* art
= m_tabs
.GetArtProvider();
2581 return art
->GetBestTabCtrlSize(this,
2583 m_requested_bmp_size
);
2587 wxAuiTabArt
* wxAuiNotebook
::GetArtProvider() const
2589 return m_tabs
.GetArtProvider();
2592 void wxAuiNotebook
::SetWindowStyleFlag(long style
)
2594 wxControl
::SetWindowStyleFlag(style
);
2596 m_flags
= (unsigned int)style
;
2598 // if the control is already initialized
2599 if (m_mgr
.GetManagedWindow() == (wxWindow
*)this)
2601 // let all of the tab children know about the new style
2603 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2604 size_t i
, pane_count
= all_panes
.GetCount();
2605 for (i
= 0; i
< pane_count
; ++i
)
2607 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2608 if (pane
.name
== wxT("dummy"))
2610 wxTabFrame
* tabframe
= (wxTabFrame
*)pane
.window
;
2611 wxAuiTabCtrl
* tabctrl
= tabframe
->m_tabs
;
2612 tabctrl
->SetFlags(m_flags
);
2613 tabframe
->DoSizing();
2621 bool wxAuiNotebook
::AddPage(wxWindow
* page
,
2622 const wxString
& caption
,
2624 const wxBitmap
& bitmap
)
2626 return InsertPage(GetPageCount(), page
, caption
, select
, bitmap
);
2629 bool wxAuiNotebook
::InsertPage(size_t page_idx
,
2631 const wxString
& caption
,
2633 const wxBitmap
& bitmap
)
2635 wxAuiNotebookPage info
;
2637 info
.caption
= caption
;
2638 info
.bitmap
= bitmap
;
2639 info
.active
= false;
2641 // if there are currently no tabs, the first added
2642 // tab must be active
2643 if (m_tabs
.GetPageCount() == 0)
2646 m_tabs
.InsertPage(page
, info
, page_idx
);
2648 wxAuiTabCtrl
* active_tabctrl
= GetActiveTabCtrl();
2649 if (page_idx
>= active_tabctrl
->GetPageCount())
2650 active_tabctrl
->AddPage(page
, info
);
2652 active_tabctrl
->InsertPage(page
, info
, page_idx
);
2654 UpdateTabCtrlHeight();
2656 active_tabctrl
->DoShowHide();
2660 int idx
= m_tabs
.GetIdxFromWindow(page
);
2661 wxASSERT_MSG(idx
!= -1, wxT("Invalid Page index returned on wxAuiNotebook::InsertPage()"));
2670 // DeletePage() removes a tab from the multi-notebook,
2671 // and destroys the window as well
2672 bool wxAuiNotebook
::DeletePage(size_t page_idx
)
2674 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
2676 if (!RemovePage(page_idx
))
2679 // actually destroy the window now
2680 if (wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
2682 // delete the child frame with pending delete, as is
2683 // customary with frame windows
2684 if (!wxPendingDelete
.Member(wnd
))
2685 wxPendingDelete
.Append(wnd
);
2697 // RemovePage() removes a tab from the multi-notebook,
2698 // but does not destroy the window
2699 bool wxAuiNotebook
::RemovePage(size_t page_idx
)
2701 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(page_idx
);
2702 wxWindow
* new_active
= NULL
;
2704 // find out which onscreen tab ctrl owns this tab
2707 if (!FindTab(wnd
, &ctrl
, &ctrl_idx
))
2710 // find a new page and set it as active
2711 int new_idx
= ctrl_idx
+1;
2712 if (new_idx
>= (int)ctrl
->GetPageCount())
2713 new_idx
= ctrl_idx
-1;
2715 if (new_idx
>= 0 && new_idx
< (int)ctrl
->GetPageCount())
2717 new_active
= ctrl
->GetWindowFromIdx(new_idx
);
2721 // set the active page to the first page that
2722 // isn't the one being deleted
2723 size_t i
, page_count
= m_tabs
.GetPageCount();
2724 for (i
= 0; i
< page_count
; ++i
)
2726 wxWindow
* w
= m_tabs
.GetWindowFromIdx(i
);
2729 new_active
= m_tabs
.GetWindowFromIdx(i
);
2735 // remove the tab from main catalog
2736 if (!m_tabs
.RemovePage(wnd
))
2739 // remove the tab from the onscreen tab ctrl
2740 ctrl
->RemovePage(wnd
);
2743 RemoveEmptyTabFrames();
2745 // set new active pane
2749 SetSelection(m_tabs
.GetIdxFromWindow(new_active
));
2755 // GetPageIndex() returns the index of the page, or -1 if the
2756 // page could not be located in the notebook
2757 int wxAuiNotebook
::GetPageIndex(wxWindow
* page_wnd
) const
2759 return m_tabs
.GetIdxFromWindow(page_wnd
);
2764 // SetPageText() changes the tab caption of the specified page
2765 bool wxAuiNotebook
::SetPageText(size_t page_idx
, const wxString
& text
)
2767 if (page_idx
>= m_tabs
.GetPageCount())
2770 // update our own tab catalog
2771 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2772 page_info
.caption
= text
;
2774 // update what's on screen
2777 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
2779 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
2780 info
.caption
= text
;
2789 bool wxAuiNotebook
::SetPageBitmap(size_t page_idx
, const wxBitmap
& bitmap
)
2791 if (page_idx
>= m_tabs
.GetPageCount())
2794 // update our own tab catalog
2795 wxAuiNotebookPage
& page_info
= m_tabs
.GetPage(page_idx
);
2796 page_info
.bitmap
= bitmap
;
2798 // tab height might have changed
2799 UpdateTabCtrlHeight();
2801 // update what's on screen
2804 if (FindTab(page_info
.window
, &ctrl
, &ctrl_idx
))
2806 wxAuiNotebookPage
& info
= ctrl
->GetPage(ctrl_idx
);
2807 info
.bitmap
= bitmap
;
2816 // GetSelection() returns the index of the currently active page
2817 int wxAuiNotebook
::GetSelection() const
2822 // SetSelection() sets the currently active page
2823 size_t wxAuiNotebook
::SetSelection(size_t new_page
)
2825 wxWindow
* wnd
= m_tabs
.GetWindowFromIdx(new_page
);
2829 wxAuiNotebookEvent
evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING
, m_windowId
);
2830 evt
.SetSelection(new_page
);
2831 evt
.SetOldSelection(m_curpage
);
2832 evt
.SetEventObject(this);
2833 if (!GetEventHandler()->ProcessEvent(evt
) || evt
.IsAllowed())
2835 int old_curpage
= m_curpage
;
2836 m_curpage
= new_page
;
2838 // program allows the page change
2839 evt
.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED
);
2840 (void)GetEventHandler()->ProcessEvent(evt
);
2845 if (FindTab(wnd
, &ctrl
, &ctrl_idx
))
2847 m_tabs
.SetActivePage(wnd
);
2849 ctrl
->SetActivePage(ctrl_idx
);
2856 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2857 size_t i
, pane_count
= all_panes
.GetCount();
2858 for (i
= 0; i
< pane_count
; ++i
)
2860 wxAuiPaneInfo
& pane
= all_panes
.Item(i
);
2861 if (pane
.name
== wxT("dummy"))
2863 wxAuiTabCtrl
* tabctrl
= ((wxTabFrame
*)pane
.window
)->m_tabs
;
2864 if (tabctrl
!= ctrl
)
2865 tabctrl
->SetSelectedFont(m_normal_font
);
2867 tabctrl
->SetSelectedFont(m_selected_font
);
2880 // GetPageCount() returns the total number of
2881 // pages managed by the multi-notebook
2882 size_t wxAuiNotebook
::GetPageCount() const
2884 return m_tabs
.GetPageCount();
2887 // GetPage() returns the wxWindow pointer of the
2889 wxWindow
* wxAuiNotebook
::GetPage(size_t page_idx
) const
2891 wxASSERT(page_idx
< m_tabs
.GetPageCount());
2893 return m_tabs
.GetWindowFromIdx(page_idx
);
2896 // DoSizing() performs all sizing operations in each tab control
2897 void wxAuiNotebook
::DoSizing()
2899 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2900 size_t i
, pane_count
= all_panes
.GetCount();
2901 for (i
= 0; i
< pane_count
; ++i
)
2903 if (all_panes
.Item(i
).name
== wxT("dummy"))
2906 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2907 tabframe
->DoSizing();
2911 // GetActiveTabCtrl() returns the active tab control. It is
2912 // called to determine which control gets new windows being added
2913 wxAuiTabCtrl
* wxAuiNotebook
::GetActiveTabCtrl()
2915 if (m_curpage
>= 0 && m_curpage
< (int)m_tabs
.GetPageCount())
2920 // find the tab ctrl with the current page
2921 if (FindTab(m_tabs
.GetPage(m_curpage
).window
,
2928 // no current page, just find the first tab ctrl
2929 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2930 size_t i
, pane_count
= all_panes
.GetCount();
2931 for (i
= 0; i
< pane_count
; ++i
)
2933 if (all_panes
.Item(i
).name
== wxT("dummy"))
2936 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2937 return tabframe
->m_tabs
;
2940 // If there is no tabframe at all, create one
2941 wxTabFrame
* tabframe
= new wxTabFrame
;
2942 tabframe
->SetTabCtrlHeight(m_tab_ctrl_height
);
2943 tabframe
->m_tabs
= new wxAuiTabCtrl(this,
2948 tabframe
->m_tabs
->SetFlags(m_flags
);
2949 tabframe
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
2950 m_mgr
.AddPane(tabframe
,
2951 wxAuiPaneInfo().Center().CaptionVisible(false));
2955 return tabframe
->m_tabs
;
2958 // FindTab() finds the tab control that currently contains the window as well
2959 // as the index of the window in the tab control. It returns true if the
2960 // window was found, otherwise false.
2961 bool wxAuiNotebook
::FindTab(wxWindow
* page
, wxAuiTabCtrl
** ctrl
, int* idx
)
2963 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
2964 size_t i
, pane_count
= all_panes
.GetCount();
2965 for (i
= 0; i
< pane_count
; ++i
)
2967 if (all_panes
.Item(i
).name
== wxT("dummy"))
2970 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
2972 int page_idx
= tabframe
->m_tabs
->GetIdxFromWindow(page
);
2975 *ctrl
= tabframe
->m_tabs
;
2985 void wxAuiNotebook
::OnEraseBackground(wxEraseEvent
&)
2989 void wxAuiNotebook
::OnSize(wxSizeEvent
& evt
)
2991 UpdateHintWindowSize();
2996 void wxAuiNotebook
::OnTabClicked(wxCommandEvent
& command_evt
)
2998 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
3000 wxAuiTabCtrl
* ctrl
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3001 wxASSERT(ctrl
!= NULL
);
3003 wxWindow
* wnd
= ctrl
->GetWindowFromIdx(evt
.GetSelection());
3004 wxASSERT(wnd
!= NULL
);
3006 int idx
= m_tabs
.GetIdxFromWindow(wnd
);
3007 wxASSERT(idx
!= -1);
3012 void wxAuiNotebook
::OnTabBeginDrag(wxCommandEvent
&)
3017 void wxAuiNotebook
::OnTabDragMotion(wxCommandEvent
& evt
)
3019 wxPoint screen_pt
= ::wxGetMousePosition();
3020 wxPoint client_pt
= ScreenToClient(screen_pt
);
3023 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3024 wxAuiTabCtrl
* dest_tabs
= GetTabCtrlFromPoint(client_pt
);
3026 if (dest_tabs
== src_tabs
)
3030 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
3033 // always hide the hint for inner-tabctrl drag
3036 // if tab moving is not allowed, leave
3037 if (!(m_flags
& wxAUI_NB_TAB_MOVE
))
3042 wxPoint pt
= dest_tabs
->ScreenToClient(screen_pt
);
3043 wxWindow
* dest_location_tab
;
3045 // this is an inner-tab drag/reposition
3046 if (dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &dest_location_tab
))
3048 int src_idx
= evt
.GetSelection();
3049 int dest_idx
= dest_tabs
->GetIdxFromWindow(dest_location_tab
);
3051 // prevent jumpy drag
3052 if ((src_idx
== dest_idx
) || dest_idx
== -1 ||
3053 (src_idx
> dest_idx
&& m_last_drag_x
<= pt
.x
) ||
3054 (src_idx
< dest_idx
&& m_last_drag_x
>= pt
.x
))
3056 m_last_drag_x
= pt
.x
;
3061 wxWindow
* src_tab
= dest_tabs
->GetWindowFromIdx(src_idx
);
3062 dest_tabs
->MovePage(src_tab
, dest_idx
);
3063 dest_tabs
->SetActivePage((size_t)dest_idx
);
3064 dest_tabs
->DoShowHide();
3065 dest_tabs
->Refresh();
3066 m_last_drag_x
= pt
.x
;
3074 // if external drag is allowed, check if the tab is being dragged
3075 // over a different wxAuiNotebook control
3076 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
3078 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(screen_pt
);
3080 // if we aren't over any window, stop here
3084 // make sure we are not over the hint window
3085 if (!tab_ctrl
->IsKindOf(CLASSINFO(wxFrame
)))
3089 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
3091 tab_ctrl
= tab_ctrl
->GetParent();
3096 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
3100 wxRect hint_rect
= tab_ctrl
->GetClientRect();
3101 tab_ctrl
->ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
3102 m_mgr
.ShowHint(hint_rect
);
3111 // we are either over a hint window, or not over a tab
3112 // window, and there is no where to drag to, so exit
3119 // if there are less than two panes, split can't happen, so leave
3120 if (m_tabs
.GetPageCount() < 2)
3123 // if tab moving is not allowed, leave
3124 if (!(m_flags
& wxAUI_NB_TAB_SPLIT
))
3130 src_tabs
->SetCursor(wxCursor(wxCURSOR_SIZING
));
3136 wxRect hint_rect
= dest_tabs
->GetRect();
3137 ClientToScreen(&hint_rect
.x
, &hint_rect
.y
);
3138 m_mgr
.ShowHint(hint_rect
);
3142 m_mgr
.DrawHintRect(m_dummy_wnd
, client_pt
, zero
);
3148 void wxAuiNotebook
::OnTabEndDrag(wxCommandEvent
& command_evt
)
3150 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
3155 wxAuiTabCtrl
* src_tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3156 wxAuiTabCtrl
* dest_tabs
= NULL
;
3159 // set cursor back to an arrow
3160 src_tabs
->SetCursor(wxCursor(wxCURSOR_ARROW
));
3163 // get the mouse position, which will be used to determine the drop point
3164 wxPoint mouse_screen_pt
= ::wxGetMousePosition();
3165 wxPoint mouse_client_pt
= ScreenToClient(mouse_screen_pt
);
3169 // check for an external move
3170 if (m_flags
& wxAUI_NB_TAB_EXTERNAL_MOVE
)
3172 wxWindow
* tab_ctrl
= ::wxFindWindowAtPoint(mouse_screen_pt
);
3176 if (tab_ctrl
->IsKindOf(CLASSINFO(wxAuiTabCtrl
)))
3178 tab_ctrl
= tab_ctrl
->GetParent();
3183 wxAuiNotebook
* nb
= (wxAuiNotebook
*)tab_ctrl
->GetParent();
3187 // find out from the destination control
3188 // if it's ok to drop this tab here
3189 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_ALLOW_DND
, m_windowId
);
3190 e
.SetSelection(evt
.GetSelection());
3191 e
.SetOldSelection(evt
.GetSelection());
3192 e
.SetEventObject(this);
3193 e
.SetDragSource(this);
3194 e
.Veto(); // dropping must be explicitly approved by control owner
3196 nb
->GetEventHandler()->ProcessEvent(e
);
3200 // no answer or negative answer
3206 int src_idx
= evt
.GetSelection();
3207 wxWindow
* src_page
= src_tabs
->GetWindowFromIdx(src_idx
);
3209 // get main index of the page
3210 int main_idx
= m_tabs
.GetIdxFromWindow(src_page
);
3212 // make a copy of the page info
3213 wxAuiNotebookPage page_info
= m_tabs
.GetPage((size_t)main_idx
);
3215 // remove the page from the source notebook
3216 RemovePage(main_idx
);
3218 // reparent the page
3219 src_page
->Reparent(nb
);
3222 // found out the insert idx
3223 wxAuiTabCtrl
* dest_tabs
= (wxAuiTabCtrl
*)tab_ctrl
;
3224 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
3226 wxWindow
* target
= NULL
;
3227 int insert_idx
= -1;
3228 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
3231 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
3235 // add the page to the new notebook
3236 if (insert_idx
== -1)
3237 insert_idx
= dest_tabs
->GetPageCount();
3238 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
3239 nb
->m_tabs
.AddPage(page_info
.window
, page_info
);
3242 dest_tabs
->DoShowHide();
3243 dest_tabs
->Refresh();
3245 // set the selection in the destination tab control
3246 nb
->SetSelection(nb
->m_tabs
.GetIdxFromWindow(page_info
.window
));
3256 // only perform a tab split if it's allowed
3257 if ((m_flags
& wxAUI_NB_TAB_SPLIT
) && m_tabs
.GetPageCount() >= 2)
3259 // If the pointer is in an existing tab frame, do a tab insert
3260 wxWindow
* hit_wnd
= ::wxFindWindowAtPoint(mouse_screen_pt
);
3261 wxTabFrame
* tab_frame
= (wxTabFrame
*)GetTabFrameFromTabCtrl(hit_wnd
);
3262 int insert_idx
= -1;
3265 dest_tabs
= tab_frame
->m_tabs
;
3267 if (dest_tabs
== src_tabs
)
3271 wxPoint pt
= dest_tabs
->ScreenToClient(mouse_screen_pt
);
3272 wxWindow
* target
= NULL
;
3273 dest_tabs
->TabHitTest(pt
.x
, pt
.y
, &target
);
3276 insert_idx
= dest_tabs
->GetIdxFromWindow(target
);
3282 wxRect rect
= m_mgr
.CalculateHintRect(m_dummy_wnd
,
3287 // there is no suitable drop location here, exit out
3291 // If there is no tabframe at all, create one
3292 wxTabFrame
* new_tabs
= new wxTabFrame
;
3293 new_tabs
->m_rect
= wxRect(wxPoint(0,0), CalculateNewSplitSize());
3294 new_tabs
->SetTabCtrlHeight(m_tab_ctrl_height
);
3295 new_tabs
->m_tabs
= new wxAuiTabCtrl(this,
3300 new_tabs
->m_tabs
->SetArtProvider(m_tabs
.GetArtProvider()->Clone());
3301 new_tabs
->m_tabs
->SetFlags(m_flags
);
3303 m_mgr
.AddPane(new_tabs
,
3304 wxAuiPaneInfo().Bottom().CaptionVisible(false),
3307 dest_tabs
= new_tabs
->m_tabs
;
3312 // remove the page from the source tabs
3313 wxAuiNotebookPage page_info
= src_tabs
->GetPage(evt
.GetSelection());
3314 page_info
.active
= false;
3315 src_tabs
->RemovePage(page_info
.window
);
3316 if (src_tabs
->GetPageCount() > 0)
3318 src_tabs
->SetActivePage((size_t)0);
3319 src_tabs
->DoShowHide();
3320 src_tabs
->Refresh();
3325 // add the page to the destination tabs
3326 if (insert_idx
== -1)
3327 insert_idx
= dest_tabs
->GetPageCount();
3328 dest_tabs
->InsertPage(page_info
.window
, page_info
, insert_idx
);
3330 if (src_tabs
->GetPageCount() == 0)
3332 RemoveEmptyTabFrames();
3336 dest_tabs
->DoShowHide();
3337 dest_tabs
->Refresh();
3339 SetSelection(m_tabs
.GetIdxFromWindow(page_info
.window
));
3341 UpdateHintWindowSize();
3347 wxAuiTabCtrl
* wxAuiNotebook
::GetTabCtrlFromPoint(const wxPoint
& pt
)
3349 // if we've just removed the last tab from the source
3350 // tab set, the remove the tab control completely
3351 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
3352 size_t i
, pane_count
= all_panes
.GetCount();
3353 for (i
= 0; i
< pane_count
; ++i
)
3355 if (all_panes
.Item(i
).name
== wxT("dummy"))
3358 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3359 if (tabframe
->m_tab_rect
.Contains(pt
))
3360 return tabframe
->m_tabs
;
3366 wxWindow
* wxAuiNotebook
::GetTabFrameFromTabCtrl(wxWindow
* tab_ctrl
)
3368 // if we've just removed the last tab from the source
3369 // tab set, the remove the tab control completely
3370 wxAuiPaneInfoArray
& all_panes
= m_mgr
.GetAllPanes();
3371 size_t i
, pane_count
= all_panes
.GetCount();
3372 for (i
= 0; i
< pane_count
; ++i
)
3374 if (all_panes
.Item(i
).name
== wxT("dummy"))
3377 wxTabFrame
* tabframe
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3378 if (tabframe
->m_tabs
== tab_ctrl
)
3387 void wxAuiNotebook
::RemoveEmptyTabFrames()
3389 // if we've just removed the last tab from the source
3390 // tab set, the remove the tab control completely
3391 wxAuiPaneInfoArray all_panes
= m_mgr
.GetAllPanes();
3392 size_t i
, pane_count
= all_panes
.GetCount();
3393 for (i
= 0; i
< pane_count
; ++i
)
3395 if (all_panes
.Item(i
).name
== wxT("dummy"))
3398 wxTabFrame
* tab_frame
= (wxTabFrame
*)all_panes
.Item(i
).window
;
3399 if (tab_frame
->m_tabs
->GetPageCount() == 0)
3401 m_mgr
.DetachPane(tab_frame
);
3403 // use pending delete because sometimes during
3404 // window closing, refreshs are pending
3405 if (!wxPendingDelete
.Member(tab_frame
->m_tabs
))
3406 wxPendingDelete
.Append(tab_frame
->m_tabs
);
3407 //tab_frame->m_tabs->Destroy();
3414 // check to see if there is still a center pane;
3415 // if there isn't, make a frame the center pane
3416 wxAuiPaneInfoArray panes
= m_mgr
.GetAllPanes();
3417 pane_count
= panes
.GetCount();
3418 wxWindow
* first_good
= NULL
;
3419 bool center_found
= false;
3420 for (i
= 0; i
< pane_count
; ++i
)
3422 if (panes
.Item(i
).name
== wxT("dummy"))
3424 if (panes
.Item(i
).dock_direction
== wxAUI_DOCK_CENTRE
)
3425 center_found
= true;
3427 first_good
= panes
.Item(i
).window
;
3430 if (!center_found
&& first_good
)
3432 m_mgr
.GetPane(first_good
).Centre();
3438 void wxAuiNotebook
::OnChildFocus(wxChildFocusEvent
& evt
)
3440 int idx
= m_tabs
.GetIdxFromWindow(evt
.GetWindow());
3441 if (idx
!= -1 && idx
!= m_curpage
)
3448 void wxAuiNotebook
::OnTabButton(wxCommandEvent
& command_evt
)
3450 wxAuiNotebookEvent
& evt
= (wxAuiNotebookEvent
&)command_evt
;
3451 wxAuiTabCtrl
* tabs
= (wxAuiTabCtrl
*)evt
.GetEventObject();
3453 int button_id
= evt
.GetInt();
3455 if (button_id
== wxAUI_BUTTON_CLOSE
)
3457 int selection
= tabs
->GetActivePage();
3459 if (selection
!= -1)
3461 wxWindow
* close_wnd
= tabs
->GetWindowFromIdx(selection
);
3464 // ask owner if it's ok to close the tab
3465 wxAuiNotebookEvent
e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CLOSE
, m_windowId
);
3466 e
.SetSelection(m_tabs
.GetIdxFromWindow(close_wnd
));
3467 e
.SetOldSelection(evt
.GetSelection());
3468 e
.SetEventObject(this);
3469 GetEventHandler()->ProcessEvent(e
);
3474 if (close_wnd
->IsKindOf(CLASSINFO(wxAuiMDIChildFrame
)))
3480 int main_idx
= m_tabs
.GetIdxFromWindow(close_wnd
);
3481 DeletePage(main_idx
);