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