]> git.saurik.com Git - wxWidgets.git/blob - src/aui/auibook.cpp
various close-button styles implemented in wxAuiNotebook
[wxWidgets.git] / src / aui / auibook.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/aui/auibook.cpp
3 // Purpose: wxaui: wx advanced user interface - notebook
4 // Author: Benjamin I. Williams
5 // Modified by:
6 // Created: 2006-06-28
7 // Copyright: (C) Copyright 2006, Kirix Corporation, All Rights Reserved
8 // Licence: wxWindows Library Licence, Version 3.1
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ----------------------------------------------------------------------------
12 // headers
13 // ----------------------------------------------------------------------------
14
15 #include "wx/wxprec.h"
16
17 #ifdef __BORLANDC__
18 #pragma hdrstop
19 #endif
20
21 #if wxUSE_AUI
22
23 #include "wx/aui/auibook.h"
24
25 #ifndef WX_PRECOMP
26 #include "wx/settings.h"
27 #include "wx/image.h"
28 #endif
29
30 #include "wx/aui/tabmdi.h"
31 #include "wx/dcbuffer.h"
32
33 #include "wx/arrimpl.cpp"
34 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray)
35 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray)
36
37 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING)
38 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED)
39 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BUTTON)
40 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG)
41 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG)
42 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION)
43
44
45
46 IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent, wxEvent)
47
48
49
50
51
52 // This functions are here for this proof of concept
53 // and will be factored out later. See dockart.cpp
54 static wxColor StepColour(const wxColor& c, int percent)
55 {
56 int r = c.Red(), g = c.Green(), b = c.Blue();
57 return wxColour((unsigned char)wxMin((r*percent)/100,255),
58 (unsigned char)wxMin((g*percent)/100,255),
59 (unsigned char)wxMin((b*percent)/100,255));
60 }
61
62 // This functions are here for this proof of concept
63 // and will be factored out later. See dockart.cpp
64 static wxBitmap BitmapFromBits(const unsigned char bits[], int w, int h,
65 const wxColour& color)
66 {
67 wxImage img = wxBitmap((const char*)bits, w, h).ConvertToImage();
68 img.Replace(0,0,0,123,123,123);
69 img.Replace(255,255,255,color.Red(),color.Green(),color.Blue());
70 img.SetMaskColour(123,123,123);
71 return wxBitmap(img);
72 }
73
74 static void DrawButtonS(wxDC& dc,
75 const wxRect& _rect,
76 const wxBitmap& bmp,
77 const wxColour& bkcolour,
78 int button_state)
79 {
80 wxRect rect = _rect;
81
82 if (button_state == wxAUI_BUTTON_STATE_PRESSED)
83 {
84 rect.x++;
85 rect.y++;
86 }
87
88 if (button_state == wxAUI_BUTTON_STATE_HOVER ||
89 button_state == wxAUI_BUTTON_STATE_PRESSED)
90 {
91 dc.SetBrush(wxBrush(StepColour(bkcolour, 120)));
92 dc.SetPen(wxPen(StepColour(bkcolour, 70)));
93
94 // draw the background behind the button
95 dc.DrawRectangle(rect.x, rect.y, 15, 15);
96 }
97
98 // draw the button itself
99 dc.DrawBitmap(bmp, rect.x, rect.y, true);
100 }
101
102
103
104
105
106 // -- wxAuiDefaultTabArt class implementation --
107
108 wxAuiDefaultTabArt::wxAuiDefaultTabArt()
109 {
110 m_normal_font = *wxNORMAL_FONT;
111 m_selected_font = *wxNORMAL_FONT;
112 m_selected_font.SetWeight(wxBOLD);
113 m_measuring_font = m_selected_font;
114
115 wxColour base_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
116
117 wxColour background_colour = StepColour(base_colour, 95);
118 wxColour normaltab_colour = base_colour;
119 wxColour selectedtab_colour = *wxWHITE;
120
121 m_bkbrush = wxBrush(background_colour);
122 m_normal_bkbrush = wxBrush(normaltab_colour);
123 m_normal_bkpen = wxPen(normaltab_colour);
124 m_selected_bkbrush = wxBrush(selectedtab_colour);
125 m_selected_bkpen = wxPen(selectedtab_colour);
126
127
128 #if defined( __WXMAC__ )
129 static unsigned char close_bits[]={
130 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0xFE, 0x03, 0xF8, 0x01, 0xF0, 0x19, 0xF3,
131 0xB8, 0xE3, 0xF0, 0xE1, 0xE0, 0xE0, 0xF0, 0xE1, 0xB8, 0xE3, 0x19, 0xF3,
132 0x01, 0xF0, 0x03, 0xF8, 0x0F, 0xFE, 0xFF, 0xFF };
133 #elif defined( __WXGTK__)
134 static unsigned char close_bits[]={
135 0xff, 0xff, 0xff, 0xff, 0x07, 0xf0, 0xfb, 0xef, 0xdb, 0xed, 0x8b, 0xe8,
136 0x1b, 0xec, 0x3b, 0xee, 0x1b, 0xec, 0x8b, 0xe8, 0xdb, 0xed, 0xfb, 0xef,
137 0x07, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
138 #else
139 static unsigned char close_bits[]={
140 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xfb,0xcf,0xf9,
141 0x9f,0xfc,0x3f,0xfe,0x3f,0xfe,0x9f,0xfc,0xcf,0xf9,0xef,0xfb,
142 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
143 #endif
144
145 static unsigned char left_bits[] = {
146 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0xfe, 0x3f, 0xfe,
147 0x1f, 0xfe, 0x0f, 0xfe, 0x1f, 0xfe, 0x3f, 0xfe, 0x7f, 0xfe, 0xff, 0xfe,
148 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
149
150 static unsigned char right_bits[] = {
151 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0x9f, 0xff, 0x1f, 0xff,
152 0x1f, 0xfe, 0x1f, 0xfc, 0x1f, 0xfe, 0x1f, 0xff, 0x9f, 0xff, 0xdf, 0xff,
153 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
154
155 m_active_close_bmp = BitmapFromBits(close_bits, 16, 16, *wxBLACK);
156 m_disabled_close_bmp = BitmapFromBits(close_bits, 16, 16, wxColour(128,128,128));
157
158 m_active_left_bmp = BitmapFromBits(left_bits, 16, 16, *wxBLACK);
159 m_disabled_left_bmp = BitmapFromBits(left_bits, 16, 16, wxColour(128,128,128));
160
161 m_active_right_bmp = BitmapFromBits(right_bits, 16, 16, *wxBLACK);
162 m_disabled_right_bmp = BitmapFromBits(right_bits, 16, 16, wxColour(128,128,128));
163 }
164
165 wxAuiDefaultTabArt::~wxAuiDefaultTabArt()
166 {
167 }
168
169 void wxAuiDefaultTabArt::DrawBackground(wxDC* dc,
170 const wxRect& rect)
171 {
172 // draw background
173 dc->SetBrush(m_bkbrush);
174 dc->SetPen(*wxTRANSPARENT_PEN);
175 dc->DrawRectangle(-1, -1, rect.GetWidth()+2, rect.GetHeight()+2);
176
177 // draw base line
178 dc->SetPen(*wxGREY_PEN);
179 dc->DrawLine(0, rect.GetHeight()-1, rect.GetWidth(), rect.GetHeight()-1);
180 }
181
182
183 // DrawTab() draws an individual tab.
184 //
185 // dc - output dc
186 // in_rect - rectangle the tab should be confined to
187 // caption - tab's caption
188 // active - whether or not the tab is active
189 // out_rect - actual output rectangle
190 // x_extent - the advance x; where the next tab should start
191
192 void wxAuiDefaultTabArt::DrawTab(wxDC* dc,
193 const wxRect& in_rect,
194 const wxString& caption_text,
195 bool active,
196 int close_button_state,
197 wxRect* out_tab_rect,
198 wxRect* out_button_rect,
199 int* x_extent)
200 {
201 wxCoord normal_textx, normal_texty;
202 wxCoord selected_textx, selected_texty;
203 wxCoord textx, texty;
204
205 // if the caption is empty, measure some temporary text
206 wxString caption = caption_text;
207 if (caption_text.empty())
208 caption = wxT("Xj");
209
210 dc->SetFont(m_selected_font);
211 dc->GetTextExtent(caption, &selected_textx, &selected_texty);
212
213 dc->SetFont(m_normal_font);
214 dc->GetTextExtent(caption, &normal_textx, &normal_texty);
215
216 // figure out the size of the tab
217 wxSize tab_size = GetTabSize(dc, caption, active, close_button_state, x_extent);
218
219 wxCoord tab_height = tab_size.y;
220 wxCoord tab_width = tab_size.x;
221 wxCoord tab_x = in_rect.x;
222 wxCoord tab_y = in_rect.y + in_rect.height - tab_height;
223
224 // select pen, brush and font for the tab to be drawn
225
226 if (active)
227 {
228 dc->SetPen(m_selected_bkpen);
229 dc->SetBrush(m_selected_bkbrush);
230 dc->SetFont(m_selected_font);
231 textx = selected_textx;
232 texty = selected_texty;
233 }
234 else
235 {
236 dc->SetPen(m_normal_bkpen);
237 dc->SetBrush(m_normal_bkbrush);
238 dc->SetFont(m_normal_font);
239 textx = normal_textx;
240 texty = normal_texty;
241 }
242
243
244 // -- draw line --
245
246 wxPoint points[7];
247 points[0].x = tab_x;
248 points[0].y = tab_y + tab_height - 1;
249 points[1].x = tab_x + tab_height - 3;
250 points[1].y = tab_y + 2;
251 points[2].x = tab_x + tab_height + 3;
252 points[2].y = tab_y;
253 points[3].x = tab_x + tab_width - 2;
254 points[3].y = tab_y;
255 points[4].x = tab_x + tab_width;
256 points[4].y = tab_y + 2;
257 points[5].x = tab_x + tab_width;
258 points[5].y = tab_y + tab_height - 1;
259 points[6] = points[0];
260
261
262 dc->DrawPolygon(6, points);
263
264 dc->SetPen(*wxGREY_PEN);
265
266 //dc->DrawLines(active ? 6 : 7, points);
267 dc->DrawLines(7, points);
268
269
270 int text_offset;
271
272 int close_button_width = 0;
273 if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
274 {
275 close_button_width = m_active_close_bmp.GetWidth();
276 text_offset = tab_x + (tab_height/2) + ((tab_width-close_button_width)/2) - (textx/2);
277 }
278 else
279 {
280 text_offset = tab_x + (tab_height/3) + (tab_width/2) - (textx/2);
281 }
282
283
284 // draw tab text
285 dc->DrawText(caption,
286 text_offset,
287 (tab_y + tab_height)/2 - (texty/2) + 1);
288
289
290 // draw close button if necessary
291 if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
292 {
293 wxBitmap bmp;
294 if (active)
295 bmp = m_active_close_bmp;
296 else
297 bmp = m_disabled_close_bmp;
298
299 wxRect rect(tab_x + tab_width - close_button_width - 1, tab_y + 1,
300 close_button_width, tab_height - 1);
301 DrawButtonS(*dc, rect, bmp, *wxWHITE, close_button_state);
302
303 *out_button_rect = rect;
304 }
305
306
307 *out_tab_rect = wxRect(tab_x, tab_y, tab_width, tab_height);
308 }
309
310
311 wxSize wxAuiDefaultTabArt::GetTabSize(wxDC* dc,
312 const wxString& caption,
313 bool WXUNUSED(active),
314 int close_button_state,
315 int* x_extent)
316 {
317 wxCoord measured_textx, measured_texty;
318
319 dc->SetFont(m_measuring_font);
320 dc->GetTextExtent(caption, &measured_textx, &measured_texty);
321
322 wxCoord tab_height = measured_texty + 4;
323 wxCoord tab_width = measured_textx + tab_height + 5;
324
325 if (close_button_state != wxAUI_BUTTON_STATE_HIDDEN)
326 tab_width += m_active_close_bmp.GetWidth();
327
328 *x_extent = tab_width - (tab_height/2) - 1;
329
330 return wxSize(tab_width, tab_height);
331 }
332
333
334 void wxAuiDefaultTabArt::DrawButton(
335 wxDC* dc,
336 const wxRect& in_rect,
337 int bitmap_id,
338 int button_state,
339 int orientation,
340 const wxBitmap& bitmap_override,
341 wxRect* out_rect)
342 {
343 wxBitmap bmp;
344 wxRect rect;
345
346 if (bitmap_override.IsOk())
347 {
348 bmp = bitmap_override;
349 }
350 else
351 {
352 switch (bitmap_id)
353 {
354 case wxAUI_BUTTON_CLOSE:
355 if (button_state & wxAUI_BUTTON_STATE_DISABLED)
356 bmp = m_disabled_close_bmp;
357 else
358 bmp = m_active_close_bmp;
359 break;
360 case wxAUI_BUTTON_LEFT:
361 if (button_state & wxAUI_BUTTON_STATE_DISABLED)
362 bmp = m_disabled_left_bmp;
363 else
364 bmp = m_active_left_bmp;
365 break;
366 case wxAUI_BUTTON_RIGHT:
367 if (button_state & wxAUI_BUTTON_STATE_DISABLED)
368 bmp = m_disabled_right_bmp;
369 else
370 bmp = m_active_right_bmp;
371 break;
372 }
373 }
374
375 if (!bmp.IsOk())
376 return;
377
378 rect = in_rect;
379
380 if (orientation == wxLEFT)
381 {
382 rect.SetX(in_rect.x);
383 rect.SetY(((in_rect.y + in_rect.height)/2) - (bmp.GetHeight()/2));
384 rect.SetWidth(bmp.GetWidth());
385 rect.SetHeight(bmp.GetHeight());
386 }
387 else
388 {
389 rect = wxRect(in_rect.x + in_rect.width - bmp.GetWidth(),
390 ((in_rect.y + in_rect.height)/2) - (bmp.GetHeight()/2),
391 bmp.GetWidth(), bmp.GetHeight());
392 }
393
394
395 DrawButtonS(*dc, rect, bmp, *wxWHITE, button_state);
396
397 *out_rect = rect;
398 }
399
400
401
402 int wxAuiDefaultTabArt::GetBestTabCtrlSize(wxWindow* wnd)
403 {
404 wxClientDC dc(wnd);
405 dc.SetFont(m_measuring_font);
406 int x_ext = 0;
407 wxSize s = GetTabSize(&dc, wxT("ABCDEFGHIj"), true, wxAUI_BUTTON_STATE_HIDDEN, &x_ext);
408 return s.y+3;
409 }
410
411 void wxAuiDefaultTabArt::SetNormalFont(const wxFont& font)
412 {
413 m_normal_font = font;
414 }
415
416 void wxAuiDefaultTabArt::SetSelectedFont(const wxFont& font)
417 {
418 m_selected_font = font;
419 }
420
421 void wxAuiDefaultTabArt::SetMeasuringFont(const wxFont& font)
422 {
423 m_measuring_font = font;
424 }
425
426
427
428
429
430
431 // -- wxAuiTabContainer class implementation --
432
433
434 // wxAuiTabContainer is a class which contains information about each
435 // tab. It also can render an entire tab control to a specified DC.
436 // It's not a window class itself, because this code will be used by
437 // the wxFrameMananger, where it is disadvantageous to have separate
438 // windows for each tab control in the case of "docked tabs"
439
440 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window
441 // which can be used as a tab control in the normal sense.
442
443
444 wxAuiTabContainer::wxAuiTabContainer()
445 {
446 m_tab_offset = 0;
447 m_flags = 0;
448 m_art = new wxAuiDefaultTabArt;
449
450 AddButton(wxAUI_BUTTON_LEFT, wxLEFT);
451 AddButton(wxAUI_BUTTON_RIGHT, wxRIGHT);
452 AddButton(wxAUI_BUTTON_CLOSE, wxRIGHT);
453 }
454
455 wxAuiTabContainer::~wxAuiTabContainer()
456 {
457 delete m_art;
458 }
459
460 void wxAuiTabContainer::SetArtProvider(wxAuiTabArt* art)
461 {
462 delete m_art;
463 m_art = art;
464 }
465
466 wxAuiTabArt* wxAuiTabContainer::GetArtProvider()
467 {
468 return m_art;
469 }
470
471 void wxAuiTabContainer::SetFlags(unsigned int flags)
472 {
473 m_flags = flags;
474
475 // check for new close button settings
476 RemoveButton(wxAUI_BUTTON_CLOSE);
477 if (flags & wxAUI_NB_CLOSE_BUTTON)
478 {
479 AddButton(wxAUI_BUTTON_CLOSE, wxRIGHT);
480 }
481 }
482
483 unsigned int wxAuiTabContainer::GetFlags() const
484 {
485 return m_flags;
486 }
487
488
489 void wxAuiTabContainer::SetNormalFont(const wxFont& font)
490 {
491 m_art->SetNormalFont(font);
492 }
493
494 void wxAuiTabContainer::SetSelectedFont(const wxFont& font)
495 {
496 m_art->SetSelectedFont(font);
497 }
498
499 void wxAuiTabContainer::SetMeasuringFont(const wxFont& font)
500 {
501 m_art->SetMeasuringFont(font);
502 }
503
504 void wxAuiTabContainer::SetRect(const wxRect& rect)
505 {
506 m_rect = rect;
507 }
508
509 bool wxAuiTabContainer::AddPage(wxWindow* page,
510 const wxAuiNotebookPage& info)
511 {
512 wxAuiNotebookPage page_info;
513 page_info = info;
514 page_info.window = page;
515
516 m_pages.Add(page_info);
517
518 return true;
519 }
520
521 bool wxAuiTabContainer::InsertPage(wxWindow* page,
522 const wxAuiNotebookPage& info,
523 size_t idx)
524 {
525 wxAuiNotebookPage page_info;
526 page_info = info;
527 page_info.window = page;
528
529 if (idx >= m_pages.GetCount())
530 m_pages.Add(page_info);
531 else
532 m_pages.Insert(page_info, idx);
533
534 return true;
535 }
536
537 bool wxAuiTabContainer::MovePage(wxWindow* page,
538 size_t new_idx)
539 {
540 int idx = GetIdxFromWindow(page);
541 if (idx == -1)
542 return false;
543
544 // get page entry, make a copy of it
545 wxAuiNotebookPage p = GetPage(idx);
546
547 // remove old page entry
548 RemovePage(page);
549
550 // insert page where it should be
551 InsertPage(page, p, new_idx);
552
553 return true;
554 }
555
556 bool wxAuiTabContainer::RemovePage(wxWindow* wnd)
557 {
558 size_t i, page_count = m_pages.GetCount();
559 for (i = 0; i < page_count; ++i)
560 {
561 wxAuiNotebookPage& page = m_pages.Item(i);
562 if (page.window == wnd)
563 {
564 m_pages.RemoveAt(i);
565 return true;
566 }
567 }
568
569 return false;
570 }
571
572 bool wxAuiTabContainer::SetActivePage(wxWindow* wnd)
573 {
574 bool found = false;
575
576 size_t i, page_count = m_pages.GetCount();
577 for (i = 0; i < page_count; ++i)
578 {
579 wxAuiNotebookPage& page = m_pages.Item(i);
580 if (page.window == wnd)
581 {
582 page.active = true;
583 found = true;
584 }
585 else
586 {
587 page.active = false;
588 }
589 }
590
591 return found;
592 }
593
594 void wxAuiTabContainer::SetNoneActive()
595 {
596 size_t i, page_count = m_pages.GetCount();
597 for (i = 0; i < page_count; ++i)
598 {
599 wxAuiNotebookPage& page = m_pages.Item(i);
600 page.active = false;
601 }
602 }
603
604 bool wxAuiTabContainer::SetActivePage(size_t page)
605 {
606 if (page >= m_pages.GetCount())
607 return false;
608
609 return SetActivePage(m_pages.Item(page).window);
610 }
611
612 int wxAuiTabContainer::GetActivePage() const
613 {
614 size_t i, page_count = m_pages.GetCount();
615 for (i = 0; i < page_count; ++i)
616 {
617 wxAuiNotebookPage& page = m_pages.Item(i);
618 if (page.active)
619 return i;
620 }
621
622 return -1;
623 }
624
625 wxWindow* wxAuiTabContainer::GetWindowFromIdx(size_t idx) const
626 {
627 if (idx >= m_pages.GetCount())
628 return NULL;
629
630 return m_pages[idx].window;
631 }
632
633 int wxAuiTabContainer::GetIdxFromWindow(wxWindow* wnd) const
634 {
635 size_t i, page_count = m_pages.GetCount();
636 for (i = 0; i < page_count; ++i)
637 {
638 wxAuiNotebookPage& page = m_pages.Item(i);
639 if (page.window == wnd)
640 return i;
641 }
642 return -1;
643 }
644
645 wxAuiNotebookPage& wxAuiTabContainer::GetPage(size_t idx)
646 {
647 wxASSERT_MSG(idx < m_pages.GetCount(), wxT("Invalid Page index"));
648
649 return m_pages[idx];
650 }
651
652 wxAuiNotebookPageArray& wxAuiTabContainer::GetPages()
653 {
654 return m_pages;
655 }
656
657 size_t wxAuiTabContainer::GetPageCount() const
658 {
659 return m_pages.GetCount();
660 }
661
662 void wxAuiTabContainer::AddButton(int id,
663 int location,
664 const wxBitmap& normal_bitmap,
665 const wxBitmap& disabled_bitmap)
666 {
667 wxAuiTabContainerButton button;
668 button.id = id;
669 button.bitmap = normal_bitmap;
670 button.dis_bitmap = disabled_bitmap;
671 button.location = location;
672 button.cur_state = wxAUI_BUTTON_STATE_NORMAL;
673
674 m_buttons.Add(button);
675 }
676
677 void wxAuiTabContainer::RemoveButton(int id)
678 {
679 size_t i, button_count = m_buttons.GetCount();
680
681 for (i = 0; i < button_count; ++i)
682 {
683 if (m_buttons.Item(i).id == id)
684 {
685 m_buttons.RemoveAt(i);
686 return;
687 }
688 }
689 }
690
691
692
693 size_t wxAuiTabContainer::GetTabOffset() const
694 {
695 return m_tab_offset;
696 }
697
698 void wxAuiTabContainer::SetTabOffset(size_t offset)
699 {
700 m_tab_offset = offset;
701 }
702
703 // Render() renders the tab catalog to the specified DC
704 // It is a virtual function and can be overridden to
705 // provide custom drawing capabilities
706 void wxAuiTabContainer::Render(wxDC* raw_dc)
707 {
708 wxMemoryDC dc;
709 wxBitmap bmp;
710 size_t i;
711 size_t page_count = m_pages.GetCount();
712 size_t button_count = m_buttons.GetCount();
713
714 // create off-screen bitmap
715 bmp.Create(m_rect.GetWidth(), m_rect.GetHeight());
716 dc.SelectObject(bmp);
717
718
719 // find out if size of tabs is larger than can be
720 // afforded on screen
721 int total_width = 0;
722 int visible_width = 0;
723 for (i = 0; i < page_count; ++i)
724 {
725 wxAuiNotebookPage& page = m_pages.Item(i);
726
727 // determine if a close button is on this tab
728 bool close_button = false;
729 if ((m_flags & wxAUI_NB_CLOSE_ON_ALL_TABS) != 0 ||
730 ((m_flags & wxAUI_NB_CLOSE_ON_ACTIVE_TAB) != 0 && page.active))
731 {
732 close_button = true;
733 }
734
735
736 int x_extent = 0;
737 wxSize size = m_art->GetTabSize(&dc,
738 page.caption,
739 page.active,
740 close_button ?
741 wxAUI_BUTTON_STATE_NORMAL :
742 wxAUI_BUTTON_STATE_HIDDEN,
743 &x_extent);
744
745 if (i+1 < page_count)
746 total_width += x_extent;
747 else
748 total_width += size.x;
749
750 if (i >= m_tab_offset)
751 {
752 if (i+1 < page_count)
753 visible_width += x_extent;
754 else
755 visible_width += size.x;
756 }
757 }
758
759 if (total_width > m_rect.GetWidth() - 20 || m_tab_offset != 0)
760 {
761 // show left/right buttons
762 for (i = 0; i < button_count; ++i)
763 {
764 wxAuiTabContainerButton& button = m_buttons.Item(i);
765 if (button.id == wxAUI_BUTTON_LEFT ||
766 button.id == wxAUI_BUTTON_RIGHT)
767 {
768 button.cur_state &= ~wxAUI_BUTTON_STATE_HIDDEN;
769 }
770 }
771 }
772 else
773 {
774 // hide left/right buttons
775 for (i = 0; i < button_count; ++i)
776 {
777 wxAuiTabContainerButton& button = m_buttons.Item(i);
778 if (button.id == wxAUI_BUTTON_LEFT ||
779 button.id == wxAUI_BUTTON_RIGHT)
780 {
781 button.cur_state |= wxAUI_BUTTON_STATE_HIDDEN;
782 }
783 }
784 }
785
786 // determine whether left button should be enabled
787 for (i = 0; i < button_count; ++i)
788 {
789 wxAuiTabContainerButton& button = m_buttons.Item(i);
790 if (button.id == wxAUI_BUTTON_LEFT)
791 {
792 if (m_tab_offset == 0)
793 button.cur_state |= wxAUI_BUTTON_STATE_DISABLED;
794 else
795 button.cur_state &= ~wxAUI_BUTTON_STATE_DISABLED;
796 }
797 if (button.id == wxAUI_BUTTON_RIGHT)
798 {
799 if (visible_width < m_rect.GetWidth() - ((int)button_count*16))
800 button.cur_state |= wxAUI_BUTTON_STATE_DISABLED;
801 else
802 button.cur_state &= ~wxAUI_BUTTON_STATE_DISABLED;
803 }
804 }
805
806
807
808 // draw background
809 m_art->DrawBackground(&dc, m_rect);
810
811 // draw buttons
812 int left_buttons_width = 0;
813 int right_buttons_width = 0;
814
815 int offset = 0;
816
817 // draw the buttons on the right side
818 offset = m_rect.x + m_rect.width;
819 for (i = 0; i < button_count; ++i)
820 {
821 wxAuiTabContainerButton& button = m_buttons.Item(button_count - i - 1);
822
823 if (button.location != wxRIGHT)
824 continue;
825 if (button.cur_state & wxAUI_BUTTON_STATE_HIDDEN)
826 continue;
827
828 wxRect button_rect = m_rect;
829 button_rect.SetY(1);
830 button_rect.SetWidth(offset);
831
832 m_art->DrawButton(&dc,
833 button_rect,
834 button.id,
835 button.cur_state,
836 wxRIGHT,
837 wxNullBitmap,
838 &button.rect);
839
840 offset -= button.rect.GetWidth();
841 right_buttons_width += button.rect.GetWidth();
842 }
843
844
845
846 offset = 0;
847
848 // draw the buttons on the left side
849
850 for (i = 0; i < button_count; ++i)
851 {
852 wxAuiTabContainerButton& button = m_buttons.Item(button_count - i - 1);
853
854 if (button.location != wxLEFT)
855 continue;
856 if (button.cur_state & wxAUI_BUTTON_STATE_HIDDEN)
857 continue;
858
859 wxRect button_rect(offset, 1, 1000, m_rect.height);
860
861 m_art->DrawButton(&dc,
862 button_rect,
863 button.id,
864 button.cur_state,
865 wxLEFT,
866 wxNullBitmap,
867 &button.rect);
868
869 offset += button.rect.GetWidth();
870 left_buttons_width += button.rect.GetWidth();
871 }
872
873 offset = left_buttons_width;
874
875 // set a clipping region to the tabs don't draw over the buttons
876 dc.SetClippingRegion(left_buttons_width, 0,
877 m_rect.GetWidth() - right_buttons_width - left_buttons_width - 2,
878 m_rect.GetHeight());
879
880
881
882 // prepare the tab-close-button array
883 while (m_tab_close_buttons.GetCount() < page_count)
884 {
885 wxAuiTabContainerButton tempbtn;
886 tempbtn.id = wxAUI_BUTTON_CLOSE;
887 tempbtn.location = wxCENTER;
888 tempbtn.cur_state = wxAUI_BUTTON_STATE_HIDDEN;
889 m_tab_close_buttons.Add(tempbtn);
890 }
891
892 for (i = 0; i < m_tab_offset; ++i)
893 {
894 // buttons before the tab offset must be set to hidden
895 m_tab_close_buttons.Item(i).cur_state = wxAUI_BUTTON_STATE_HIDDEN;
896 }
897
898
899 // draw the tabs
900
901 size_t active = 999;
902 int active_offset = 0;
903
904 int x_extent = 0;
905 wxRect rect = m_rect;
906 rect.y = 0;
907 rect.width = 1000;
908 rect.height = m_rect.height;
909
910 for (i = m_tab_offset; i < page_count; ++i)
911 {
912 wxAuiNotebookPage& page = m_pages.Item(i);
913 wxAuiTabContainerButton& tab_button = m_tab_close_buttons.Item(i);
914
915 // determine if a close button is on this tab
916 bool close_button = false;
917 if ((m_flags & wxAUI_NB_CLOSE_ON_ALL_TABS) != 0 ||
918 ((m_flags & wxAUI_NB_CLOSE_ON_ACTIVE_TAB) != 0 && page.active))
919 {
920 close_button = true;
921 if (tab_button.cur_state == wxAUI_BUTTON_STATE_HIDDEN)
922 {
923 tab_button.id = wxAUI_BUTTON_CLOSE;
924 tab_button.cur_state = wxAUI_BUTTON_STATE_NORMAL;
925 tab_button.location = wxCENTER;
926 }
927 }
928 else
929 {
930 tab_button.cur_state = wxAUI_BUTTON_STATE_HIDDEN;
931 }
932
933 rect.x = offset;
934
935 m_art->DrawTab(&dc,
936 rect,
937 page.caption,
938 page.active,
939 tab_button.cur_state,
940 &page.rect,
941 &tab_button.rect,
942 &x_extent);
943
944 if (page.active)
945 {
946 active = i;
947 active_offset = offset;
948 }
949
950 offset += x_extent;
951 }
952
953 // draw the active tab again so it stands in the foreground
954 if (active >= m_tab_offset && active < m_pages.GetCount())
955 {
956 wxAuiNotebookPage& page = m_pages.Item(active);
957
958 wxAuiTabContainerButton& tab_button = m_tab_close_buttons.Item(active);
959
960 // determine if a close button is on this tab
961 bool close_button = false;
962 if ((m_flags & wxAUI_NB_CLOSE_ON_ALL_TABS) != 0 ||
963 ((m_flags & wxAUI_NB_CLOSE_ON_ACTIVE_TAB) != 0 && page.active))
964 {
965 close_button = true;
966 }
967
968 rect.x = active_offset;
969 m_art->DrawTab(&dc,
970 rect,
971 page.caption,
972 page.active,
973 tab_button.cur_state,
974 &page.rect,
975 &tab_button.rect,
976 &x_extent);
977 }
978
979 dc.DestroyClippingRegion();
980
981 raw_dc->Blit(m_rect.x, m_rect.y,
982 m_rect.GetWidth(), m_rect.GetHeight(),
983 &dc, 0, 0);
984 }
985
986
987 // TabHitTest() tests if a tab was hit, passing the window pointer
988 // back if that condition was fulfilled. The function returns
989 // true if a tab was hit, otherwise false
990 bool wxAuiTabContainer::TabHitTest(int x, int y, wxWindow** hit) const
991 {
992 if (!m_rect.Contains(x,y))
993 return false;
994
995 wxAuiTabContainerButton* btn = NULL;
996 if (ButtonHitTest(x, y, &btn))
997 {
998 if (m_buttons.Index(*btn) != wxNOT_FOUND)
999 return false;
1000 }
1001
1002 size_t i, page_count = m_pages.GetCount();
1003
1004 for (i = m_tab_offset; i < page_count; ++i)
1005 {
1006 wxAuiNotebookPage& page = m_pages.Item(i);
1007 if (page.rect.Contains(x,y))
1008 {
1009 if (hit)
1010 *hit = page.window;
1011 return true;
1012 }
1013 }
1014
1015 return false;
1016 }
1017
1018 // ButtonHitTest() tests if a button was hit. The function returns
1019 // true if a button was hit, otherwise false
1020 bool wxAuiTabContainer::ButtonHitTest(int x, int y,
1021 wxAuiTabContainerButton** hit) const
1022 {
1023 if (!m_rect.Contains(x,y))
1024 return false;
1025
1026 size_t i, button_count;
1027
1028
1029 button_count = m_buttons.GetCount();
1030 for (i = 0; i < button_count; ++i)
1031 {
1032 wxAuiTabContainerButton& button = m_buttons.Item(i);
1033 if (button.rect.Contains(x,y))
1034 {
1035 if (hit)
1036 *hit = &button;
1037 return true;
1038 }
1039 }
1040
1041 button_count = m_tab_close_buttons.GetCount();
1042 for (i = 0; i < button_count; ++i)
1043 {
1044 wxAuiTabContainerButton& button = m_tab_close_buttons.Item(i);
1045 if (button.rect.Contains(x,y))
1046 {
1047 if (hit)
1048 *hit = &button;
1049 return true;
1050 }
1051 }
1052
1053 return false;
1054 }
1055
1056
1057
1058 // the utility function ShowWnd() is the same as show,
1059 // except it handles wxAuiMDIChildFrame windows as well,
1060 // as the Show() method on this class is "unplugged"
1061 static void ShowWnd(wxWindow* wnd, bool show)
1062 {
1063 if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
1064 {
1065 wxAuiMDIChildFrame* cf = (wxAuiMDIChildFrame*)wnd;
1066 cf->DoShow(show);
1067 }
1068 else
1069 {
1070 wnd->Show(show);
1071 }
1072 }
1073
1074
1075 // DoShowHide() this function shows the active window, then
1076 // hides all of the other windows (in that order)
1077 void wxAuiTabContainer::DoShowHide()
1078 {
1079 wxAuiNotebookPageArray& pages = GetPages();
1080 size_t i, page_count = pages.GetCount();
1081
1082 // show new active page first
1083 for (i = 0; i < page_count; ++i)
1084 {
1085 wxAuiNotebookPage& page = pages.Item(i);
1086 if (page.active)
1087 {
1088 ShowWnd(page.window, true);
1089 break;
1090 }
1091 }
1092
1093 // hide all other pages
1094 for (i = 0; i < page_count; ++i)
1095 {
1096 wxAuiNotebookPage& page = pages.Item(i);
1097 ShowWnd(page.window, page.active);
1098 }
1099 }
1100
1101
1102
1103
1104
1105
1106 // -- wxAuiTabCtrl class implementation --
1107
1108
1109
1110 BEGIN_EVENT_TABLE(wxAuiTabCtrl, wxControl)
1111 EVT_PAINT(wxAuiTabCtrl::OnPaint)
1112 EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground)
1113 EVT_SIZE(wxAuiTabCtrl::OnSize)
1114 EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown)
1115 EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp)
1116 EVT_MOTION(wxAuiTabCtrl::OnMotion)
1117 EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow)
1118 EVT_AUINOTEBOOK_BUTTON(-1, wxAuiTabCtrl::OnButton)
1119 END_EVENT_TABLE()
1120
1121
1122 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow* parent,
1123 wxWindowID id,
1124 const wxPoint& pos,
1125 const wxSize& size,
1126 long style) : wxControl(parent, id, pos, size, style)
1127 {
1128 m_click_pt = wxDefaultPosition;
1129 m_is_dragging = false;
1130 m_hover_button = NULL;
1131 }
1132
1133 wxAuiTabCtrl::~wxAuiTabCtrl()
1134 {
1135 }
1136
1137 void wxAuiTabCtrl::OnPaint(wxPaintEvent&)
1138 {
1139 wxPaintDC dc(this);
1140
1141 dc.SetFont(GetFont());
1142
1143 if (GetPageCount() > 0)
1144 Render(&dc);
1145 }
1146
1147 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent& WXUNUSED(evt))
1148 {
1149 }
1150
1151 void wxAuiTabCtrl::OnSize(wxSizeEvent& evt)
1152 {
1153 wxSize s = evt.GetSize();
1154 wxRect r(0, 0, s.GetWidth(), s.GetHeight());
1155 SetRect(r);
1156 }
1157
1158 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt)
1159 {
1160 CaptureMouse();
1161 m_click_pt = wxDefaultPosition;
1162 m_is_dragging = false;
1163 m_click_tab = NULL;
1164
1165 wxWindow* wnd;
1166 if (TabHitTest(evt.m_x, evt.m_y, &wnd))
1167 {
1168 wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId);
1169 e.SetSelection(GetIdxFromWindow(wnd));
1170 e.SetOldSelection(GetActivePage());
1171 e.SetEventObject(this);
1172 GetEventHandler()->ProcessEvent(e);
1173
1174 m_click_pt.x = evt.m_x;
1175 m_click_pt.y = evt.m_y;
1176 m_click_tab = wnd;
1177 }
1178
1179 if (m_hover_button)
1180 {
1181 m_hover_button->cur_state = wxAUI_BUTTON_STATE_PRESSED;
1182 Refresh();
1183 Update();
1184 }
1185 }
1186
1187 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent&)
1188 {
1189 if (GetCapture() == this)
1190 ReleaseMouse();
1191
1192 if (m_is_dragging)
1193 {
1194 wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, m_windowId);
1195 evt.SetSelection(GetIdxFromWindow(m_click_tab));
1196 evt.SetOldSelection(evt.GetSelection());
1197 evt.SetEventObject(this);
1198 GetEventHandler()->ProcessEvent(evt);
1199 return;
1200 }
1201
1202 if (m_hover_button)
1203 {
1204 m_hover_button->cur_state = wxAUI_BUTTON_STATE_HOVER;
1205 Refresh();
1206 Update();
1207
1208 if (!(m_hover_button->cur_state & wxAUI_BUTTON_STATE_DISABLED))
1209 {
1210 wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON, m_windowId);
1211 evt.SetInt(m_hover_button->id);
1212 evt.SetEventObject(this);
1213 GetEventHandler()->ProcessEvent(evt);
1214 }
1215 }
1216
1217 m_click_pt = wxDefaultPosition;
1218 m_is_dragging = false;
1219 m_click_tab = NULL;
1220 }
1221
1222 void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt)
1223 {
1224 wxPoint pos = evt.GetPosition();
1225
1226 // check if the mouse is hovering above a button
1227 wxAuiTabContainerButton* button;
1228 if (ButtonHitTest(pos.x, pos.y, &button))
1229 {
1230 if (m_hover_button && button != m_hover_button)
1231 {
1232 m_hover_button->cur_state = wxAUI_BUTTON_STATE_NORMAL;
1233 m_hover_button = NULL;
1234 Refresh();
1235 Update();
1236 }
1237
1238 if (button->cur_state != wxAUI_BUTTON_STATE_HOVER)
1239 {
1240 button->cur_state = wxAUI_BUTTON_STATE_HOVER;
1241 Refresh();
1242 Update();
1243 m_hover_button = button;
1244 return;
1245 }
1246 }
1247 else
1248 {
1249 if (m_hover_button)
1250 {
1251 m_hover_button->cur_state = wxAUI_BUTTON_STATE_NORMAL;
1252 m_hover_button = NULL;
1253 Refresh();
1254 Update();
1255 }
1256 }
1257
1258
1259 if (!evt.LeftIsDown() || m_click_pt == wxDefaultPosition)
1260 return;
1261
1262 if (m_is_dragging)
1263 {
1264 wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, m_windowId);
1265 evt.SetSelection(GetIdxFromWindow(m_click_tab));
1266 evt.SetOldSelection(evt.GetSelection());
1267 evt.SetEventObject(this);
1268 GetEventHandler()->ProcessEvent(evt);
1269 return;
1270 }
1271
1272
1273 int drag_x_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_X);
1274 int drag_y_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_Y);
1275
1276 if (abs(pos.x - m_click_pt.x) > drag_x_threshold ||
1277 abs(pos.y - m_click_pt.y) > drag_y_threshold)
1278 {
1279 wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, m_windowId);
1280 evt.SetSelection(GetIdxFromWindow(m_click_tab));
1281 evt.SetOldSelection(evt.GetSelection());
1282 evt.SetEventObject(this);
1283 GetEventHandler()->ProcessEvent(evt);
1284
1285 m_is_dragging = true;
1286 }
1287 }
1288
1289 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent& WXUNUSED(event))
1290 {
1291 if (m_hover_button)
1292 {
1293 m_hover_button->cur_state = wxAUI_BUTTON_STATE_NORMAL;
1294 m_hover_button = NULL;
1295 Refresh();
1296 Update();
1297 }
1298 }
1299
1300 void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent& event)
1301 {
1302 int button = event.GetInt();
1303
1304 if (button == wxAUI_BUTTON_LEFT || button == wxAUI_BUTTON_RIGHT)
1305 {
1306 if (button == wxAUI_BUTTON_LEFT)
1307 {
1308 if (GetTabOffset() > 0)
1309 {
1310 SetTabOffset(GetTabOffset()-1);
1311 Refresh();
1312 Update();
1313 }
1314 }
1315 else
1316 {
1317 SetTabOffset(GetTabOffset()+1);
1318 Refresh();
1319 Update();
1320 }
1321 }
1322 else
1323 {
1324 event.Skip();
1325 }
1326 }
1327
1328 // wxTabFrame is an interesting case. It's important that all child pages
1329 // of the multi-notebook control are all actually children of that control
1330 // (and not grandchildren). wxTabFrame facilitates this. There is one
1331 // instance of wxTabFrame for each tab control inside the multi-notebook.
1332 // It's important to know that wxTabFrame is not a real window, but it merely
1333 // used to capture the dimensions/positioning of the internal tab control and
1334 // it's managed page windows
1335
1336 class wxTabFrame : public wxWindow
1337 {
1338 public:
1339
1340 wxTabFrame()
1341 {
1342 m_tabs = NULL;
1343 m_rect = wxRect(0,0,200,200);
1344 m_tab_ctrl_height = 20;
1345 }
1346
1347 void SetTabCtrlHeight(int h)
1348 {
1349 m_tab_ctrl_height = h;
1350 }
1351
1352 void DoSetSize(int x, int y,
1353 int width, int height,
1354 int WXUNUSED(sizeFlags = wxSIZE_AUTO))
1355 {
1356 m_rect = wxRect(x, y, width, height);
1357 DoSizing();
1358 }
1359
1360 void DoGetClientSize(int* x, int* y) const
1361 {
1362 *x = m_rect.width;
1363 *y = m_rect.height;
1364 }
1365
1366 bool Show( bool WXUNUSED(show = true) ) { return false; }
1367
1368 void DoSizing()
1369 {
1370 if (!m_tabs)
1371 return;
1372
1373 int tab_height = wxMin(m_rect.height, m_tab_ctrl_height);
1374 m_tab_rect = wxRect(m_rect.x, m_rect.y, m_rect.width, tab_height);
1375 m_tabs->SetSize(m_rect.x, m_rect.y, m_rect.width, tab_height);
1376 m_tabs->SetRect(wxRect(0, 0, m_rect.width, tab_height));
1377 m_tabs->Refresh();
1378 m_tabs->Update();
1379
1380 wxAuiNotebookPageArray& pages = m_tabs->GetPages();
1381 size_t i, page_count = pages.GetCount();
1382
1383 for (i = 0; i < page_count; ++i)
1384 {
1385 wxAuiNotebookPage& page = pages.Item(i);
1386 page.window->SetSize(m_rect.x, m_rect.y+tab_height, m_rect.width, m_rect.height-tab_height);
1387
1388 if (page.window->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
1389 {
1390 wxAuiMDIChildFrame* wnd = (wxAuiMDIChildFrame*)page.window;
1391 wnd->ApplyMDIChildFrameRect();
1392 }
1393 }
1394 }
1395
1396 void DoGetSize(int* x, int* y) const
1397 {
1398 if (x)
1399 *x = m_rect.GetWidth();
1400 if (y)
1401 *y = m_rect.GetHeight();
1402 }
1403
1404 void Update()
1405 {
1406 // does nothing
1407 }
1408
1409 public:
1410
1411 wxRect m_rect;
1412 wxRect m_tab_rect;
1413 wxAuiTabCtrl* m_tabs;
1414 int m_tab_ctrl_height;
1415 };
1416
1417
1418
1419
1420
1421 // -- wxAuiNotebook class implementation --
1422
1423 BEGIN_EVENT_TABLE(wxAuiNotebook, wxControl)
1424 //EVT_ERASE_BACKGROUND(wxAuiNotebook::OnEraseBackground)
1425 //EVT_SIZE(wxAuiNotebook::OnSize)
1426 //EVT_LEFT_DOWN(wxAuiNotebook::OnLeftDown)
1427 EVT_CHILD_FOCUS(wxAuiNotebook::OnChildFocus)
1428 EVT_COMMAND_RANGE(10000, 10100,
1429 wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING,
1430 wxAuiNotebook::OnTabClicked)
1431 EVT_COMMAND_RANGE(10000, 10100,
1432 wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG,
1433 wxAuiNotebook::OnTabBeginDrag)
1434 EVT_COMMAND_RANGE(10000, 10100,
1435 wxEVT_COMMAND_AUINOTEBOOK_END_DRAG,
1436 wxAuiNotebook::OnTabEndDrag)
1437 EVT_COMMAND_RANGE(10000, 10100,
1438 wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION,
1439 wxAuiNotebook::OnTabDragMotion)
1440 EVT_COMMAND_RANGE(10000, 10100,
1441 wxEVT_COMMAND_AUINOTEBOOK_BUTTON,
1442 wxAuiNotebook::OnTabButton)
1443 END_EVENT_TABLE()
1444
1445 wxAuiNotebook::wxAuiNotebook()
1446 {
1447 m_curpage = -1;
1448 m_tab_id_counter = 10000;
1449 m_dummy_wnd = NULL;
1450 m_tab_ctrl_height = 20;
1451 }
1452
1453 wxAuiNotebook::wxAuiNotebook(wxWindow *parent,
1454 wxWindowID id,
1455 const wxPoint& pos,
1456 const wxSize& size,
1457 long style) : wxControl(parent, id, pos, size, style)
1458 {
1459 InitNotebook(style);
1460 }
1461
1462 bool wxAuiNotebook::Create(wxWindow* parent,
1463 wxWindowID id,
1464 const wxPoint& pos,
1465 const wxSize& size,
1466 long style)
1467 {
1468 if (!wxControl::Create(parent, id, pos, size, style))
1469 return false;
1470
1471 InitNotebook(style);
1472
1473 return true;
1474 }
1475
1476 // InitNotebook() contains common initialization
1477 // code called by all constructors
1478 void wxAuiNotebook::InitNotebook(long style)
1479 {
1480 m_curpage = -1;
1481 m_tab_id_counter = 10000;
1482 m_dummy_wnd = NULL;
1483 m_tab_ctrl_height = 20;
1484 m_flags = (unsigned int)style;
1485
1486 m_normal_font = *wxNORMAL_FONT;
1487 m_selected_font = *wxNORMAL_FONT;
1488 m_selected_font.SetWeight(wxBOLD);
1489
1490 // choose a default for the tab height
1491 m_tab_ctrl_height = m_tabs.GetArtProvider()->GetBestTabCtrlSize(this);
1492
1493 m_dummy_wnd = new wxWindow(this, wxID_ANY, wxPoint(0,0), wxSize(0,0));
1494 m_dummy_wnd->SetSize(200, 200);
1495 m_dummy_wnd->Show(false);
1496
1497 m_mgr.SetManagedWindow(this);
1498
1499 m_mgr.AddPane(m_dummy_wnd,
1500 wxAuiPaneInfo().Name(wxT("dummy")).Bottom().Show(false));
1501
1502 m_mgr.Update();
1503 }
1504
1505 wxAuiNotebook::~wxAuiNotebook()
1506 {
1507 m_mgr.UnInit();
1508 }
1509
1510 void wxAuiNotebook::SetArtProvider(wxAuiTabArt* art)
1511 {
1512 m_tabs.SetArtProvider(art);
1513 }
1514
1515 wxAuiTabArt* wxAuiNotebook::GetArtProvider()
1516 {
1517 return m_tabs.GetArtProvider();
1518 }
1519
1520 bool wxAuiNotebook::AddPage(wxWindow* page,
1521 const wxString& caption,
1522 bool select,
1523 const wxBitmap& bitmap)
1524 {
1525 return InsertPage(GetPageCount(), page, caption, select, bitmap);
1526 }
1527
1528 bool wxAuiNotebook::InsertPage(size_t page_idx,
1529 wxWindow* page,
1530 const wxString& caption,
1531 bool select,
1532 const wxBitmap& bitmap)
1533 {
1534 wxAuiNotebookPage info;
1535 info.window = page;
1536 info.caption = caption;
1537 info.bitmap = bitmap;
1538 info.active = false;
1539
1540 // if there are currently no tabs, the first added
1541 // tab must be active
1542 if (m_tabs.GetPageCount() == 0)
1543 info.active = true;
1544
1545 m_tabs.InsertPage(page, info, page_idx);
1546
1547 wxAuiTabCtrl* active_tabctrl = GetActiveTabCtrl();
1548 if (page_idx >= active_tabctrl->GetPageCount())
1549 active_tabctrl->AddPage(page, info);
1550 else
1551 active_tabctrl->InsertPage(page, info, page_idx);
1552
1553 DoSizing();
1554 active_tabctrl->DoShowHide();
1555
1556 if (select)
1557 {
1558 int idx = m_tabs.GetIdxFromWindow(page);
1559 wxASSERT_MSG(idx != -1, wxT("Invalid Page index returned on wxAuiNotebook::InsertPage()"));
1560
1561 SetSelection(idx);
1562 }
1563
1564 return true;
1565 }
1566
1567
1568 // DeletePage() removes a tab from the multi-notebook,
1569 // and destroys the window as well
1570 bool wxAuiNotebook::DeletePage(size_t page_idx)
1571 {
1572 wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
1573 wxWindow* new_active = NULL;
1574
1575 // find out which onscreen tab ctrl owns this tab
1576 wxAuiTabCtrl* ctrl;
1577 int ctrl_idx;
1578 if (!FindTab(wnd, &ctrl, &ctrl_idx))
1579 return false;
1580
1581 // find a new page and set it as active
1582 int new_idx = ctrl_idx+1;
1583 if (new_idx >= (int)ctrl->GetPageCount())
1584 new_idx = ctrl_idx-1;
1585
1586 if (new_idx >= 0 && new_idx < (int)ctrl->GetPageCount())
1587 {
1588 new_active = ctrl->GetWindowFromIdx(new_idx);
1589 }
1590 else
1591 {
1592 // set the active page to the first page that
1593 // isn't the one being deleted
1594 size_t i, page_count = m_tabs.GetPageCount();
1595 for (i = 0; i < page_count; ++i)
1596 {
1597 wxWindow* w = m_tabs.GetWindowFromIdx(i);
1598 if (wnd != w)
1599 {
1600 new_active = m_tabs.GetWindowFromIdx(i);
1601 break;
1602 }
1603 }
1604 }
1605
1606 // remove the tab from main catalog
1607 if (!m_tabs.RemovePage(wnd))
1608 return false;
1609
1610 // remove the tab from the onscreen tab ctrl
1611 ctrl->RemovePage(wnd);
1612
1613 // actually destroy the window now
1614 if (wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
1615 {
1616 // delete the child frame with pending delete, as is
1617 // customary with frame windows
1618 if (!wxPendingDelete.Member(wnd))
1619 wxPendingDelete.Append(wnd);
1620 }
1621 else
1622 {
1623 wnd->Destroy();
1624 }
1625
1626 RemoveEmptyTabFrames();
1627
1628 // set new active pane
1629 if (new_active)
1630 {
1631 m_curpage = -1;
1632 SetSelection(m_tabs.GetIdxFromWindow(new_active));
1633 }
1634
1635 return true;
1636 }
1637
1638
1639
1640 // RemovePage() removes a tab from the multi-notebook,
1641 // but does not destroy the window
1642 bool wxAuiNotebook::RemovePage(size_t page_idx)
1643 {
1644 // remove the tab from our own catalog
1645 wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
1646 if (!m_tabs.RemovePage(wnd))
1647 return false;
1648
1649 // remove the tab from the onscreen tab ctrl
1650 wxAuiTabCtrl* ctrl;
1651 int ctrl_idx;
1652 if (FindTab(wnd, &ctrl, &ctrl_idx))
1653 {
1654 ctrl->RemovePage(wnd);
1655 return true;
1656 }
1657
1658 return false;
1659 }
1660
1661 // SetPageText() changes the tab caption of the specified page
1662 bool wxAuiNotebook::SetPageText(size_t page_idx, const wxString& text)
1663 {
1664 if (page_idx >= m_tabs.GetPageCount())
1665 return false;
1666
1667 // update our own tab catalog
1668 wxAuiNotebookPage& page_info = m_tabs.GetPage(page_idx);
1669 page_info.caption = text;
1670
1671 // update what's on screen
1672 wxAuiTabCtrl* ctrl;
1673 int ctrl_idx;
1674 if (FindTab(page_info.window, &ctrl, &ctrl_idx))
1675 {
1676 wxAuiNotebookPage& info = ctrl->GetPage(ctrl_idx);
1677 info.caption = text;
1678 ctrl->Refresh();
1679 ctrl->Update();
1680 }
1681
1682 return true;
1683 }
1684
1685 // GetSelection() returns the index of the currently active page
1686 int wxAuiNotebook::GetSelection() const
1687 {
1688 return m_curpage;
1689 }
1690
1691 // SetSelection() sets the currently active page
1692 size_t wxAuiNotebook::SetSelection(size_t new_page)
1693 {
1694 wxWindow* wnd = m_tabs.GetWindowFromIdx(new_page);
1695 if (!wnd)
1696 return m_curpage;
1697
1698 wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId);
1699 evt.SetSelection(new_page);
1700 evt.SetOldSelection(m_curpage);
1701 evt.SetEventObject(this);
1702 if (!GetEventHandler()->ProcessEvent(evt) || evt.IsAllowed())
1703 {
1704 // program allows the page change
1705 evt.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED);
1706 (void)GetEventHandler()->ProcessEvent(evt);
1707
1708
1709
1710 wxAuiTabCtrl* ctrl;
1711 int ctrl_idx;
1712 if (FindTab(wnd, &ctrl, &ctrl_idx))
1713 {
1714 m_tabs.SetActivePage(wnd);
1715
1716 ctrl->SetActivePage(ctrl_idx);
1717 DoSizing();
1718 ctrl->DoShowHide();
1719
1720 int old_curpage = m_curpage;
1721 m_curpage = new_page;
1722
1723
1724 // set fonts
1725 wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
1726 size_t i, pane_count = all_panes.GetCount();
1727 for (i = 0; i < pane_count; ++i)
1728 {
1729 wxAuiPaneInfo& pane = all_panes.Item(i);
1730 if (pane.name == wxT("dummy"))
1731 continue;
1732 wxAuiTabCtrl* tabctrl = ((wxTabFrame*)pane.window)->m_tabs;
1733 if (tabctrl != ctrl)
1734 tabctrl->SetSelectedFont(m_normal_font);
1735 else
1736 tabctrl->SetSelectedFont(m_selected_font);
1737 tabctrl->Refresh();
1738 }
1739
1740 wnd->SetFocus();
1741
1742 return old_curpage;
1743 }
1744 }
1745
1746 return m_curpage;
1747 }
1748
1749 // GetPageCount() returns the total number of
1750 // pages managed by the multi-notebook
1751 size_t wxAuiNotebook::GetPageCount() const
1752 {
1753 return m_tabs.GetPageCount();
1754 }
1755
1756 // GetPage() returns the wxWindow pointer of the
1757 // specified page
1758 wxWindow* wxAuiNotebook::GetPage(size_t page_idx) const
1759 {
1760 wxASSERT(page_idx < m_tabs.GetPageCount());
1761
1762 return m_tabs.GetWindowFromIdx(page_idx);
1763 }
1764
1765 // DoSizing() performs all sizing operations in each tab control
1766 void wxAuiNotebook::DoSizing()
1767 {
1768 wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
1769 size_t i, pane_count = all_panes.GetCount();
1770 for (i = 0; i < pane_count; ++i)
1771 {
1772 if (all_panes.Item(i).name == wxT("dummy"))
1773 continue;
1774
1775 wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
1776 tabframe->DoSizing();
1777 }
1778 }
1779
1780 // GetActiveTabCtrl() returns the active tab control. It is
1781 // called to determine which control gets new windows being added
1782 wxAuiTabCtrl* wxAuiNotebook::GetActiveTabCtrl()
1783 {
1784 if (m_curpage >= 0 && m_curpage < (int)m_tabs.GetPageCount())
1785 {
1786 wxAuiTabCtrl* ctrl;
1787 int idx;
1788
1789 // find the tab ctrl with the current page
1790 if (FindTab(m_tabs.GetPage(m_curpage).window,
1791 &ctrl, &idx))
1792 {
1793 return ctrl;
1794 }
1795 }
1796
1797 // no current page, just find the first tab ctrl
1798 wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
1799 size_t i, pane_count = all_panes.GetCount();
1800 for (i = 0; i < pane_count; ++i)
1801 {
1802 if (all_panes.Item(i).name == wxT("dummy"))
1803 continue;
1804
1805 wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
1806 return tabframe->m_tabs;
1807 }
1808
1809 // If there is no tabframe at all, create one
1810 wxTabFrame* tabframe = new wxTabFrame;
1811 tabframe->SetTabCtrlHeight(m_tab_ctrl_height);
1812 tabframe->m_tabs = new wxAuiTabCtrl(this,
1813 m_tab_id_counter++,
1814 wxDefaultPosition,
1815 wxDefaultSize,
1816 wxNO_BORDER);
1817 tabframe->m_tabs->SetFlags(m_flags);
1818 m_mgr.AddPane(tabframe,
1819 wxAuiPaneInfo().Center().CaptionVisible(false));
1820
1821 m_mgr.Update();
1822
1823 return tabframe->m_tabs;
1824 }
1825
1826 // FindTab() finds the tab control that currently contains the window as well
1827 // as the index of the window in the tab control. It returns true if the
1828 // window was found, otherwise false.
1829 bool wxAuiNotebook::FindTab(wxWindow* page, wxAuiTabCtrl** ctrl, int* idx)
1830 {
1831 wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
1832 size_t i, pane_count = all_panes.GetCount();
1833 for (i = 0; i < pane_count; ++i)
1834 {
1835 if (all_panes.Item(i).name == wxT("dummy"))
1836 continue;
1837
1838 wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
1839
1840 int page_idx = tabframe->m_tabs->GetIdxFromWindow(page);
1841 if (page_idx != -1)
1842 {
1843 *ctrl = tabframe->m_tabs;
1844 *idx = page_idx;
1845 return true;
1846 }
1847 }
1848
1849 return false;
1850 }
1851
1852
1853 void wxAuiNotebook::OnEraseBackground(wxEraseEvent&)
1854 {
1855 }
1856
1857 void wxAuiNotebook::OnSize(wxSizeEvent&)
1858 {
1859 }
1860
1861 void wxAuiNotebook::OnTabClicked(wxCommandEvent& command_evt)
1862 {
1863 wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt;
1864
1865 wxAuiTabCtrl* ctrl = (wxAuiTabCtrl*)evt.GetEventObject();
1866 wxASSERT(ctrl != NULL);
1867
1868 wxWindow* wnd = ctrl->GetWindowFromIdx(evt.GetSelection());
1869 wxASSERT(wnd != NULL);
1870
1871 int idx = m_tabs.GetIdxFromWindow(wnd);
1872 wxASSERT(idx != -1);
1873
1874 SetSelection(idx);
1875 }
1876
1877 void wxAuiNotebook::OnTabBeginDrag(wxCommandEvent&)
1878 {
1879 m_last_drag_x = 0;
1880 }
1881
1882 void wxAuiNotebook::OnTabDragMotion(wxCommandEvent& evt)
1883 {
1884 wxPoint screen_pt = ::wxGetMousePosition();
1885 wxPoint client_pt = ScreenToClient(screen_pt);
1886 wxPoint zero(0,0);
1887
1888 wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject();
1889
1890 wxAuiTabCtrl* dest_tabs = GetTabCtrlFromPoint(client_pt);
1891 if (dest_tabs == src_tabs)
1892 {
1893 // always hide the hint for inner-tabctrl drag
1894 m_mgr.HideHint();
1895
1896 wxPoint pt = dest_tabs->ScreenToClient(screen_pt);
1897 wxWindow* dest_location_tab;
1898
1899 // this is an inner-tab drag/reposition
1900 if (dest_tabs->TabHitTest(pt.x, pt.y, &dest_location_tab))
1901 {
1902 int src_idx = evt.GetSelection();
1903 int dest_idx = dest_tabs->GetIdxFromWindow(dest_location_tab);
1904
1905 // prevent jumpy drag
1906 if ((src_idx == dest_idx) || dest_idx == -1 ||
1907 (src_idx > dest_idx && m_last_drag_x <= pt.x) ||
1908 (src_idx < dest_idx && m_last_drag_x >= pt.x))
1909 {
1910 m_last_drag_x = pt.x;
1911 return;
1912 }
1913
1914
1915 wxWindow* src_tab = dest_tabs->GetWindowFromIdx(src_idx);
1916 dest_tabs->MovePage(src_tab, dest_idx);
1917 dest_tabs->SetActivePage((size_t)dest_idx);
1918 dest_tabs->DoShowHide();
1919 dest_tabs->Refresh();
1920 m_last_drag_x = pt.x;
1921
1922 }
1923
1924 return;
1925 }
1926
1927 if (dest_tabs)
1928 {
1929 wxRect hint_rect = dest_tabs->GetRect();
1930 ClientToScreen(&hint_rect.x, &hint_rect.y);
1931 m_mgr.ShowHint(hint_rect);
1932 }
1933 else
1934 {
1935 m_mgr.DrawHintRect(m_dummy_wnd, client_pt, zero);
1936 }
1937 }
1938
1939
1940
1941 void wxAuiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
1942 {
1943 wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt;
1944
1945 m_mgr.HideHint();
1946
1947
1948 // get the mouse position, which will be used to determine the drop point
1949 wxPoint mouse_screen_pt = ::wxGetMousePosition();
1950 wxPoint mouse_client_pt = ScreenToClient(mouse_screen_pt);
1951
1952
1953 // the src tab control is the control that fired this event
1954 wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject();
1955 wxAuiTabCtrl* dest_tabs = NULL;
1956
1957
1958 // If the pointer is in an existing tab frame, do a tab insert
1959 wxWindow* hit_wnd = ::wxFindWindowAtPoint(mouse_screen_pt);
1960 wxTabFrame* tab_frame = (wxTabFrame*)GetTabFrameFromTabCtrl(hit_wnd);
1961 int insert_idx = -1;
1962 if (tab_frame)
1963 {
1964 dest_tabs = tab_frame->m_tabs;
1965
1966 if (dest_tabs == src_tabs)
1967 return;
1968
1969
1970 wxPoint pt = dest_tabs->ScreenToClient(mouse_screen_pt);
1971 wxWindow* target = NULL;
1972 dest_tabs->TabHitTest(pt.x, pt.y, &target);
1973 if (target)
1974 {
1975 insert_idx = dest_tabs->GetIdxFromWindow(target);
1976 }
1977 }
1978 else
1979 {
1980 // If there is no tabframe at all, create one
1981 wxTabFrame* new_tabs = new wxTabFrame;
1982 new_tabs->SetTabCtrlHeight(m_tab_ctrl_height);
1983 new_tabs->m_tabs = new wxAuiTabCtrl(this,
1984 m_tab_id_counter++,
1985 wxDefaultPosition,
1986 wxDefaultSize,
1987 wxNO_BORDER);
1988 new_tabs->m_tabs->SetFlags(m_flags);
1989
1990 m_mgr.AddPane(new_tabs,
1991 wxAuiPaneInfo().Bottom().CaptionVisible(false),
1992 mouse_client_pt);
1993 m_mgr.Update();
1994 dest_tabs = new_tabs->m_tabs;
1995 }
1996
1997
1998
1999 // remove the page from the source tabs
2000 wxAuiNotebookPage page_info = src_tabs->GetPage(evt.GetSelection());
2001 page_info.active = false;
2002 src_tabs->RemovePage(page_info.window);
2003 if (src_tabs->GetPageCount() > 0)
2004 {
2005 src_tabs->SetActivePage((size_t)0);
2006 src_tabs->DoShowHide();
2007 src_tabs->Refresh();
2008 }
2009
2010
2011
2012 // add the page to the destination tabs
2013 if (insert_idx == -1)
2014 insert_idx = dest_tabs->GetPageCount();
2015 dest_tabs->InsertPage(page_info.window, page_info, insert_idx);
2016
2017 if (src_tabs->GetPageCount() == 0)
2018 {
2019 RemoveEmptyTabFrames();
2020 }
2021
2022 DoSizing();
2023 dest_tabs->DoShowHide();
2024 dest_tabs->Refresh();
2025
2026 SetSelection(m_tabs.GetIdxFromWindow(page_info.window));
2027 }
2028
2029 wxAuiTabCtrl* wxAuiNotebook::GetTabCtrlFromPoint(const wxPoint& pt)
2030 {
2031 // if we've just removed the last tab from the source
2032 // tab set, the remove the tab control completely
2033 wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
2034 size_t i, pane_count = all_panes.GetCount();
2035 for (i = 0; i < pane_count; ++i)
2036 {
2037 if (all_panes.Item(i).name == wxT("dummy"))
2038 continue;
2039
2040 wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
2041 if (tabframe->m_tab_rect.Contains(pt))
2042 return tabframe->m_tabs;
2043 }
2044
2045 return NULL;
2046 }
2047
2048 wxWindow* wxAuiNotebook::GetTabFrameFromTabCtrl(wxWindow* tab_ctrl)
2049 {
2050 // if we've just removed the last tab from the source
2051 // tab set, the remove the tab control completely
2052 wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes();
2053 size_t i, pane_count = all_panes.GetCount();
2054 for (i = 0; i < pane_count; ++i)
2055 {
2056 if (all_panes.Item(i).name == wxT("dummy"))
2057 continue;
2058
2059 wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
2060 if (tabframe->m_tabs == tab_ctrl)
2061 {
2062 return tabframe;
2063 }
2064 }
2065
2066 return NULL;
2067 }
2068
2069 void wxAuiNotebook::RemoveEmptyTabFrames()
2070 {
2071 // if we've just removed the last tab from the source
2072 // tab set, the remove the tab control completely
2073 wxAuiPaneInfoArray all_panes = m_mgr.GetAllPanes();
2074 size_t i, pane_count = all_panes.GetCount();
2075 for (i = 0; i < pane_count; ++i)
2076 {
2077 if (all_panes.Item(i).name == wxT("dummy"))
2078 continue;
2079
2080 wxTabFrame* tab_frame = (wxTabFrame*)all_panes.Item(i).window;
2081 if (tab_frame->m_tabs->GetPageCount() == 0)
2082 {
2083 m_mgr.DetachPane(tab_frame);
2084
2085 // use pending delete because sometimes during
2086 // window closing, refreshs are pending
2087 if (!wxPendingDelete.Member(tab_frame->m_tabs))
2088 wxPendingDelete.Append(tab_frame->m_tabs);
2089 //tab_frame->m_tabs->Destroy();
2090
2091 delete tab_frame;
2092 }
2093 }
2094
2095
2096 // check to see if there is still a center pane;
2097 // if there isn't, make a frame the center pane
2098 wxAuiPaneInfoArray panes = m_mgr.GetAllPanes();
2099 pane_count = panes.GetCount();
2100 wxWindow* first_good = NULL;
2101 bool center_found = false;
2102 for (i = 0; i < pane_count; ++i)
2103 {
2104 if (panes.Item(i).name == wxT("dummy"))
2105 continue;
2106 if (panes.Item(i).dock_direction == wxAUI_DOCK_CENTRE)
2107 center_found = true;
2108 if (!first_good)
2109 first_good = panes.Item(i).window;
2110 }
2111
2112 if (!center_found && first_good)
2113 {
2114 m_mgr.GetPane(first_good).Centre();
2115 }
2116
2117 m_mgr.Update();
2118 }
2119
2120 void wxAuiNotebook::OnChildFocus(wxChildFocusEvent& evt)
2121 {
2122 int idx = m_tabs.GetIdxFromWindow(evt.GetWindow());
2123 if (idx != -1 && idx != m_curpage)
2124 {
2125 SetSelection(idx);
2126 }
2127 }
2128
2129
2130 void wxAuiNotebook::OnTabButton(wxCommandEvent& command_evt)
2131 {
2132 wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt;
2133 wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject();
2134
2135 int button_id = evt.GetInt();
2136
2137 if (button_id == wxAUI_BUTTON_CLOSE)
2138 {
2139 int selection = tabs->GetActivePage();
2140
2141 if (selection != -1)
2142 {
2143 wxWindow* close_wnd = tabs->GetWindowFromIdx(selection);
2144
2145 if (close_wnd->IsKindOf(CLASSINFO(wxAuiMDIChildFrame)))
2146 {
2147 close_wnd->Close();
2148 }
2149 else
2150 {
2151 int main_idx = m_tabs.GetIdxFromWindow(close_wnd);
2152 DeletePage(main_idx);
2153 }
2154 }
2155 }
2156 }
2157
2158
2159
2160
2161 #endif // wxUSE_AUI