]> git.saurik.com Git - wxWidgets.git/blob - src/aui/auibook.cpp
updated header file name in source
[wxWidgets.git] / src / aui / auibook.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/aui/notebook.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 #include "wx/aui/tabmdi.h"
25 #include "wx/dcbuffer.h"
26
27 #ifndef WX_PRECOMP
28 #endif
29
30 #include "wx/arrimpl.cpp"
31 WX_DEFINE_OBJARRAY(wxAuiNotebookPageArray)
32 WX_DEFINE_OBJARRAY(wxAuiTabContainerButtonArray)
33
34 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING)
35 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED)
36 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BUTTON)
37 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG)
38 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG)
39 DEFINE_EVENT_TYPE(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION)
40
41
42
43 IMPLEMENT_DYNAMIC_CLASS(wxAuiNotebookEvent, wxEvent)
44
45 // -- wxAuiTabContainer class implementation --
46
47
48 // wxAuiTabContainer is a class which contains information about each
49 // tab. It also can render an entire tab control to a specified DC.
50 // It's not a window class itself, because this code will be used by
51 // the wxFrameMananger, where it is disadvantageous to have separate
52 // windows for each tab control in the case of "docked tabs"
53
54 // A derived class, wxAuiTabCtrl, is an actual wxWindow-derived window
55 // which can be used as a tab control in the normal sense.
56
57
58 // This functions are here for this proof of concept
59 // and will be factored out later. See dockart.cpp
60 static wxColor StepColour(const wxColor& c, int percent)
61 {
62 int r = c.Red(), g = c.Green(), b = c.Blue();
63 return wxColour((unsigned char)wxMin((r*percent)/100,255),
64 (unsigned char)wxMin((g*percent)/100,255),
65 (unsigned char)wxMin((b*percent)/100,255));
66 }
67
68 // This functions are here for this proof of concept
69 // and will be factored out later. See dockart.cpp
70 static wxBitmap BitmapFromBits(const unsigned char bits[], int w, int h,
71 const wxColour& color)
72 {
73 wxImage img = wxBitmap((const char*)bits, w, h).ConvertToImage();
74 img.Replace(255,255,255,123,123,123);
75 img.Replace(0,0,0,color.Red(),color.Green(),color.Blue());
76 img.SetMaskColour(123,123,123);
77 return wxBitmap(img);
78 }
79
80 static void DrawButton(wxDC& dc,
81 const wxRect& _rect,
82 const wxBitmap& bmp,
83 const wxColour& bkcolour,
84 int button_state)
85 {
86 wxRect rect = _rect;
87
88 if (button_state == wxAUI_BUTTON_STATE_PRESSED)
89 {
90 rect.x++;
91 rect.y++;
92 }
93
94 if (button_state == wxAUI_BUTTON_STATE_HOVER ||
95 button_state == wxAUI_BUTTON_STATE_PRESSED)
96 {
97 dc.SetBrush(wxBrush(StepColour(bkcolour, 120)));
98 dc.SetPen(wxPen(StepColour(bkcolour, 70)));
99
100 // draw the background behind the button
101 dc.DrawRectangle(rect.x, rect.y, 15, 15);
102 }
103
104 // draw the button itself
105 dc.DrawBitmap(bmp, rect.x, rect.y, true);
106 }
107
108
109
110
111 wxAuiTabContainer::wxAuiTabContainer()
112 {
113 m_normal_font = *wxNORMAL_FONT;
114 m_selected_font = *wxNORMAL_FONT;
115 m_selected_font.SetWeight(wxBOLD);
116 m_measuring_font = m_selected_font;
117
118 wxColour base_colour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
119
120 wxColour background_colour = StepColour(base_colour, 95);
121 wxColour normaltab_colour = base_colour;
122 wxColour selectedtab_colour = *wxWHITE;
123
124 m_bkbrush = wxBrush(background_colour);
125 m_normal_bkbrush = wxBrush(normaltab_colour);
126 m_normal_bkpen = wxPen(normaltab_colour);
127 m_selected_bkbrush = wxBrush(selectedtab_colour);
128 m_selected_bkpen = wxPen(selectedtab_colour);
129 }
130
131 void wxAuiTabContainer::SetNormalFont(const wxFont& font)
132 {
133 m_normal_font = font;
134 }
135
136 void wxAuiTabContainer::SetSelectedFont(const wxFont& font)
137 {
138 m_selected_font = font;
139 }
140
141 void wxAuiTabContainer::SetMeasuringFont(const wxFont& font)
142 {
143 m_measuring_font = font;
144 }
145
146 void wxAuiTabContainer::SetRect(const wxRect& rect)
147 {
148 m_rect = rect;
149 }
150
151 bool wxAuiTabContainer::AddPage(wxWindow* page,
152 const wxAuiNotebookPage& info)
153 {
154 wxAuiNotebookPage page_info;
155 page_info = info;
156 page_info.window = page;
157
158 m_pages.Add(page_info);
159
160 return true;
161 }
162
163 bool wxAuiTabContainer::InsertPage(wxWindow* page,
164 const wxAuiNotebookPage& info,
165 size_t idx)
166 {
167 wxAuiNotebookPage page_info;
168 page_info = info;
169 page_info.window = page;
170
171 if (idx >= m_pages.GetCount())
172 m_pages.Add(page_info);
173 else
174 m_pages.Insert(page_info, idx);
175
176 return true;
177 }
178
179 bool wxAuiTabContainer::RemovePage(wxWindow* wnd)
180 {
181 size_t i, page_count = m_pages.GetCount();
182 for (i = 0; i < page_count; ++i)
183 {
184 wxAuiNotebookPage& page = m_pages.Item(i);
185 if (page.window == wnd)
186 {
187 m_pages.RemoveAt(i);
188 return true;
189 }
190 }
191
192 return false;
193 }
194
195 bool wxAuiTabContainer::SetActivePage(wxWindow* wnd)
196 {
197 bool found = false;
198
199 size_t i, page_count = m_pages.GetCount();
200 for (i = 0; i < page_count; ++i)
201 {
202 wxAuiNotebookPage& page = m_pages.Item(i);
203 if (page.window == wnd)
204 {
205 page.active = true;
206 found = true;
207 }
208 else
209 {
210 page.active = false;
211 }
212 }
213
214 return found;
215 }
216
217 void wxAuiTabContainer::SetNoneActive()
218 {
219 size_t i, page_count = m_pages.GetCount();
220 for (i = 0; i < page_count; ++i)
221 {
222 wxAuiNotebookPage& page = m_pages.Item(i);
223 page.active = false;
224 }
225 }
226
227 bool wxAuiTabContainer::SetActivePage(size_t page)
228 {
229 if (page >= m_pages.GetCount())
230 return false;
231
232 return SetActivePage(m_pages.Item(page).window);
233 }
234
235 int wxAuiTabContainer::GetActivePage() const
236 {
237 size_t i, page_count = m_pages.GetCount();
238 for (i = 0; i < page_count; ++i)
239 {
240 wxAuiNotebookPage& page = m_pages.Item(i);
241 if (page.active)
242 return i;
243 }
244
245 return -1;
246 }
247
248 wxWindow* wxAuiTabContainer::GetWindowFromIdx(size_t idx) const
249 {
250 if (idx >= m_pages.GetCount())
251 return NULL;
252
253 return m_pages[idx].window;
254 }
255
256 int wxAuiTabContainer::GetIdxFromWindow(wxWindow* wnd) const
257 {
258 size_t i, page_count = m_pages.GetCount();
259 for (i = 0; i < page_count; ++i)
260 {
261 wxAuiNotebookPage& page = m_pages.Item(i);
262 if (page.window == wnd)
263 return i;
264 }
265 return -1;
266 }
267
268 wxAuiNotebookPage& wxAuiTabContainer::GetPage(size_t idx)
269 {
270 wxASSERT_MSG(idx < m_pages.GetCount(), wxT("Invalid Page index"));
271
272 return m_pages[idx];
273 }
274
275 wxAuiNotebookPageArray& wxAuiTabContainer::GetPages()
276 {
277 return m_pages;
278 }
279
280 size_t wxAuiTabContainer::GetPageCount() const
281 {
282 return m_pages.GetCount();
283 }
284
285 void wxAuiTabContainer::AddButton(int id, const wxBitmap& bmp)
286 {
287 wxAuiTabContainerButton button;
288 button.id = id;
289 button.bitmap = bmp;
290 button.cur_state = wxAUI_BUTTON_STATE_NORMAL;
291
292 m_buttons.Add(button);
293 }
294
295
296
297 // DrawTab() draws an individual tab.
298 // As it is virtual it may be overridden.
299 //
300 // dc - output dc
301 // in_rect - rectangle the tab should be confined to
302 // caption - tab's caption
303 // active - whether or not the tab is active
304 // out_rect - actual output rectangle
305 // x_extent - the advance x; where the next tab should start
306
307 void wxAuiTabContainer::DrawTab(wxDC* dc,
308 const wxRect& in_rect,
309 const wxString& caption,
310 bool active,
311 wxRect* out_rect,
312 int* x_extent)
313 {
314 wxCoord normal_textx, normal_texty;
315 wxCoord selected_textx, selected_texty;
316 wxCoord measured_textx, measured_texty;
317 wxCoord textx, texty;
318
319
320 // measure text
321 dc->SetFont(m_measuring_font);
322 dc->GetTextExtent(caption, &measured_textx, &measured_texty);
323
324 dc->SetFont(m_selected_font);
325 dc->GetTextExtent(caption, &selected_textx, &selected_texty);
326
327 dc->SetFont(m_normal_font);
328 dc->GetTextExtent(caption, &normal_textx, &normal_texty);
329
330
331 wxCoord tab_height = measured_texty + 4;
332 wxCoord tab_width = measured_textx + tab_height + 5;
333 wxCoord tab_x = in_rect.x;
334 wxCoord tab_y = in_rect.y + in_rect.height - tab_height;
335
336
337 // select pen, brush and font for the tab to be drawn
338
339 if (active)
340 {
341 dc->SetPen(m_selected_bkpen);
342 dc->SetBrush(m_selected_bkbrush);
343 dc->SetFont(m_selected_font);
344 textx = selected_textx;
345 texty = selected_texty;
346 }
347 else
348 {
349 dc->SetPen(m_normal_bkpen);
350 dc->SetBrush(m_normal_bkbrush);
351 dc->SetFont(m_normal_font);
352 textx = normal_textx;
353 texty = normal_texty;
354 }
355
356
357 // -- draw line --
358
359 wxPoint points[7];
360 points[0].x = tab_x;
361 points[0].y = tab_y + tab_height - 1;
362 points[1].x = tab_x + tab_height - 3;
363 points[1].y = tab_y + 2;
364 points[2].x = tab_x + tab_height + 3;
365 points[2].y = tab_y;
366 points[3].x = tab_x + tab_width - 2;
367 points[3].y = tab_y;
368 points[4].x = tab_x + tab_width;
369 points[4].y = tab_y + 2;
370 points[5].x = tab_x + tab_width;
371 points[5].y = tab_y + tab_height - 1;
372 points[6] = points[0];
373
374
375 dc->DrawPolygon(6, points);
376
377 dc->SetPen(*wxGREY_PEN);
378
379 //dc->DrawLines(active ? 6 : 7, points);
380 dc->DrawLines(7, points);
381
382 // -- draw text --
383
384 dc->DrawText(caption,
385 tab_x + (tab_height/3) + (tab_width/2) - (textx/2),
386 tab_y + tab_height - texty - 2);
387
388 *out_rect = wxRect(tab_x, tab_y, tab_width, tab_height);
389 *x_extent = tab_width - (tab_height/2) - 1;
390 }
391
392
393 // Render() renders the tab catalog to the specified DC
394 // It is a virtual function and can be overridden to
395 // provide custom drawing capabilities
396 void wxAuiTabContainer::Render(wxDC* raw_dc)
397 {
398 wxMemoryDC dc;
399 wxBitmap bmp;
400 bmp.Create(m_rect.GetWidth(), m_rect.GetHeight());
401 dc.SelectObject(bmp);
402
403 // draw background
404 dc.SetBrush(m_bkbrush);
405 dc.SetPen(*wxTRANSPARENT_PEN);
406 dc.DrawRectangle(-1, -1, m_rect.GetWidth()+2, m_rect.GetHeight()+2);
407
408 // draw base line
409 dc.SetPen(*wxGREY_PEN);
410 dc.DrawLine(0, m_rect.GetHeight()-1, m_rect.GetWidth(), m_rect.GetHeight()-1);
411
412
413 size_t i, page_count = m_pages.GetCount();
414 int offset = 0;
415
416 size_t active = 999;
417 int active_offset = 0;
418
419 int x_extent = 0;
420 wxRect rect = m_rect;
421 rect.y = 0;
422 rect.width = 1000;
423 rect.height = m_rect.height;
424
425 for (i = 0; i < page_count; ++i)
426 {
427 wxAuiNotebookPage& page = m_pages.Item(i);
428
429 rect.x = offset;
430
431 DrawTab(&dc,
432 rect,
433 page.caption,
434 page.active,
435 &page.rect,
436 &x_extent);
437
438 if (page.active)
439 {
440 active = i;
441 active_offset = offset;
442 }
443
444 offset += x_extent;
445 }
446
447 // draw the active tab again so it stands in the foreground
448 if (active < m_pages.GetCount())
449 {
450 wxAuiNotebookPage& page = m_pages.Item(active);
451
452 rect.x = active_offset;
453 DrawTab(&dc,
454 rect,
455 page.caption,
456 page.active,
457 &page.rect,
458 &x_extent);
459 }
460
461 // draw the buttons
462 offset = m_rect.x + m_rect.width;
463 size_t button_count = m_buttons.GetCount();
464 for (i = 0; i < button_count; ++i)
465 {
466 wxAuiTabContainerButton& button = m_buttons.Item(button_count - i - 1);
467
468 wxRect button_rect(offset - button.bitmap.GetWidth(), 1,
469 button.bitmap.GetWidth(), button.bitmap.GetHeight());
470
471 button.rect = button_rect;
472
473 DrawButton(dc, button.rect, button.bitmap,
474 m_bkbrush.GetColour(),
475 button.cur_state);
476
477 offset -= button.bitmap.GetWidth();
478 }
479
480
481 raw_dc->Blit(m_rect.x, m_rect.y, m_rect.GetWidth(), m_rect.GetHeight(), &dc, 0, 0);
482 }
483
484
485 // TabHitTest() tests if a tab was hit, passing the window pointer
486 // back if that condition was fulfilled. The function returns
487 // true if a tab was hit, otherwise false
488 bool wxAuiTabContainer::TabHitTest(int x, int y, wxWindow** hit) const
489 {
490 if (!m_rect.Inside(x,y))
491 return false;
492
493 size_t i, page_count = m_pages.GetCount();
494
495 for (i = 0; i < page_count; ++i)
496 {
497 wxAuiNotebookPage& page = m_pages.Item(i);
498 if (page.rect.Inside(x,y))
499 {
500 *hit = page.window;
501 return true;
502 }
503 }
504
505 return false;
506 }
507
508 // ButtonHitTest() tests if a button was hit. The function returns
509 // true if a button was hit, otherwise false
510 bool wxAuiTabContainer::ButtonHitTest(int x, int y,
511 wxAuiTabContainerButton** hit) const
512 {
513 if (!m_rect.Inside(x,y))
514 return false;
515
516 size_t i, button_count = m_buttons.GetCount();
517
518 for (i = 0; i < button_count; ++i)
519 {
520 wxAuiTabContainerButton& button = m_buttons.Item(i);
521 if (button.rect.Inside(x,y))
522 {
523 *hit = &button;
524 return true;
525 }
526 }
527
528 return false;
529 }
530
531
532
533 // the utility function ShowWnd() is the same as show,
534 // except it handles wxTabMDIChildFrame windows as well,
535 // as the Show() method on this class is "unplugged"
536 static void ShowWnd(wxWindow* wnd, bool show)
537 {
538 if (wnd->IsKindOf(CLASSINFO(wxTabMDIChildFrame)))
539 {
540 wxTabMDIChildFrame* cf = (wxTabMDIChildFrame*)wnd;
541 cf->DoShow(show);
542 }
543 else
544 {
545 wnd->Show(show);
546 }
547 }
548
549
550 // DoShowHide() this function shows the active window, then
551 // hides all of the other windows (in that order)
552 void wxAuiTabContainer::DoShowHide()
553 {
554 wxAuiNotebookPageArray& pages = GetPages();
555 size_t i, page_count = pages.GetCount();
556
557 // show new active page first
558 for (i = 0; i < page_count; ++i)
559 {
560 wxAuiNotebookPage& page = pages.Item(i);
561 if (page.active)
562 {
563 ShowWnd(page.window, true);
564 break;
565 }
566 }
567
568 // hide all other pages
569 for (i = 0; i < page_count; ++i)
570 {
571 wxAuiNotebookPage& page = pages.Item(i);
572 ShowWnd(page.window, page.active);
573 }
574 }
575
576
577
578
579
580
581 // -- wxAuiTabCtrl class implementation --
582
583
584 const int wxAuiButtonClose = 101;
585
586 BEGIN_EVENT_TABLE(wxAuiTabCtrl, wxControl)
587 EVT_PAINT(wxAuiTabCtrl::OnPaint)
588 EVT_ERASE_BACKGROUND(wxAuiTabCtrl::OnEraseBackground)
589 EVT_SIZE(wxAuiTabCtrl::OnSize)
590 EVT_LEFT_DOWN(wxAuiTabCtrl::OnLeftDown)
591 EVT_LEFT_UP(wxAuiTabCtrl::OnLeftUp)
592 EVT_MOTION(wxAuiTabCtrl::OnMotion)
593 EVT_LEAVE_WINDOW(wxAuiTabCtrl::OnLeaveWindow)
594 END_EVENT_TABLE()
595
596
597 wxAuiTabCtrl::wxAuiTabCtrl(wxWindow* parent,
598 wxWindowID id,
599 const wxPoint& pos,
600 const wxSize& size,
601 long style) : wxControl(parent, id, pos, size, style)
602 {
603 m_click_pt = wxDefaultPosition;
604 m_is_dragging = false;
605 m_hover_button = NULL;
606
607 // copied from dockart-- needs to put in a common place
608 static unsigned char close_bits[]={
609 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xfb,0xcf,0xf9,
610 0x9f,0xfc,0x3f,0xfe,0x3f,0xfe,0x9f,0xfc,0xcf,0xf9,0xef,0xfb,
611 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
612
613 AddButton(101, BitmapFromBits(close_bits, 16, 16, *wxBLACK));
614 }
615
616
617 void wxAuiTabCtrl::OnPaint(wxPaintEvent&)
618 {
619 wxPaintDC dc(this);
620
621 dc.SetFont(GetFont());
622
623 if (GetPageCount() > 0)
624 Render(&dc);
625 }
626
627 void wxAuiTabCtrl::OnEraseBackground(wxEraseEvent& WXUNUSED(evt))
628 {
629 }
630
631 void wxAuiTabCtrl::OnSize(wxSizeEvent& evt)
632 {
633 wxSize s = evt.GetSize();
634 wxRect r(0, 0, s.GetWidth(), s.GetHeight());
635 SetRect(r);
636 }
637
638 void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt)
639 {
640 CaptureMouse();
641 m_click_pt = wxDefaultPosition;
642 m_is_dragging = false;
643 m_click_tab = -1;
644
645 wxWindow* wnd;
646 if (TabHitTest(evt.m_x, evt.m_y, &wnd))
647 {
648 wxAuiNotebookEvent e(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId);
649 e.SetSelection(GetIdxFromWindow(wnd));
650 e.SetOldSelection(GetActivePage());
651 e.SetEventObject(this);
652 GetEventHandler()->ProcessEvent(e);
653
654 m_click_pt.x = evt.m_x;
655 m_click_pt.y = evt.m_y;
656 m_click_tab = e.GetSelection();
657 }
658
659 if (m_hover_button)
660 {
661 m_hover_button->cur_state = wxAUI_BUTTON_STATE_PRESSED;
662 Refresh();
663 Update();
664 }
665 }
666
667 void wxAuiTabCtrl::OnLeftUp(wxMouseEvent&)
668 {
669 if (GetCapture() == this)
670 ReleaseMouse();
671
672 if (m_is_dragging)
673 {
674 wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_END_DRAG, m_windowId);
675 evt.SetSelection(m_click_tab);
676 evt.SetOldSelection(m_click_tab);
677 evt.SetEventObject(this);
678 GetEventHandler()->ProcessEvent(evt);
679 return;
680 }
681
682 if (m_hover_button)
683 {
684 m_hover_button->cur_state = wxAUI_BUTTON_STATE_HOVER;
685 Refresh();
686 Update();
687
688 wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BUTTON, m_windowId);
689 evt.SetInt(m_hover_button->id);
690 evt.SetEventObject(this);
691 GetEventHandler()->ProcessEvent(evt);
692 }
693
694 m_click_pt = wxDefaultPosition;
695 m_is_dragging = false;
696 m_click_tab = -1;
697 }
698
699 void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt)
700 {
701 wxPoint pos = evt.GetPosition();
702
703 // check if the mouse is hovering above a button
704 wxAuiTabContainerButton* button;
705 if (ButtonHitTest(pos.x, pos.y, &button))
706 {
707 if (button->cur_state != wxAUI_BUTTON_STATE_HOVER)
708 {
709 button->cur_state = wxAUI_BUTTON_STATE_HOVER;
710 Refresh();
711 Update();
712 m_hover_button = button;
713 return;
714 }
715 }
716 else
717 {
718 if (m_hover_button)
719 {
720 m_hover_button->cur_state = wxAUI_BUTTON_STATE_NORMAL;
721 m_hover_button = NULL;
722 Refresh();
723 Update();
724 }
725 }
726
727
728 if (!evt.LeftIsDown() || m_click_pt == wxDefaultPosition)
729 return;
730
731 if (m_is_dragging)
732 {
733 wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION, m_windowId);
734 evt.SetSelection(m_click_tab);
735 evt.SetOldSelection(m_click_tab);
736 evt.SetEventObject(this);
737 GetEventHandler()->ProcessEvent(evt);
738 return;
739 }
740
741
742 int drag_x_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_X);
743 int drag_y_threshold = wxSystemSettings::GetMetric(wxSYS_DRAG_Y);
744
745 if (abs(pos.x - m_click_pt.x) > drag_x_threshold ||
746 abs(pos.y - m_click_pt.y) > drag_y_threshold)
747 {
748 wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG, m_windowId);
749 evt.SetSelection(m_click_tab);
750 evt.SetOldSelection(m_click_tab);
751 evt.SetEventObject(this);
752 GetEventHandler()->ProcessEvent(evt);
753
754 m_is_dragging = true;
755 }
756 }
757
758 void wxAuiTabCtrl::OnLeaveWindow(wxMouseEvent& WXUNUSED(event))
759 {
760 if (m_hover_button)
761 {
762 m_hover_button->cur_state = wxAUI_BUTTON_STATE_NORMAL;
763 m_hover_button = NULL;
764 Refresh();
765 Update();
766 }
767 }
768
769
770 // wxTabFrame is an interesting case. It's important that all child pages
771 // of the multi-notebook control are all actually children of that control
772 // (and not grandchildren). wxTabFrame facilitates this. There is one
773 // instance of wxTabFrame for each tab control inside the multi-notebook.
774 // It's important to know that wxTabFrame is not a real window, but it merely
775 // used to capture the dimensions/positioning of the internal tab control and
776 // it's managed page windows
777
778 class wxTabFrame : public wxWindow
779 {
780 public:
781
782 wxTabFrame()
783 {
784 m_tabs = NULL;
785 m_rect = wxRect(0,0,200,200);
786 }
787
788 void DoSetSize(int x, int y,
789 int width, int height,
790 int WXUNUSED(sizeFlags = wxSIZE_AUTO))
791 {
792 m_rect = wxRect(x, y, width, height);
793 DoSizing();
794 }
795
796 void DoGetClientSize(int* x, int* y) const
797 {
798 *x = m_rect.width;
799 *y = m_rect.height;
800 }
801
802 void DoSizing()
803 {
804 if (!m_tabs)
805 return;
806
807 int tab_height = wxMin(m_rect.height, 19);
808 m_tab_rect = wxRect(m_rect.x, m_rect.y, m_rect.width, tab_height);
809 m_tabs->SetSize(m_rect.x, m_rect.y, m_rect.width, tab_height);
810 m_tabs->SetRect(wxRect(0, 0, m_rect.width, tab_height));
811 m_tabs->Refresh();
812
813 wxAuiNotebookPageArray& pages = m_tabs->GetPages();
814 size_t i, page_count = pages.GetCount();
815
816 for (i = 0; i < page_count; ++i)
817 {
818 wxAuiNotebookPage& page = pages.Item(i);
819 page.window->SetSize(m_rect.x, m_rect.y+tab_height, m_rect.width, m_rect.height-tab_height);
820
821 if (page.window->IsKindOf(CLASSINFO(wxTabMDIChildFrame)))
822 {
823 wxTabMDIChildFrame* wnd = (wxTabMDIChildFrame*)page.window;
824 wnd->ApplyMDIChildFrameRect();
825 }
826 }
827 }
828
829 public:
830
831 wxRect m_rect;
832 wxRect m_tab_rect;
833 wxAuiTabCtrl* m_tabs;
834 };
835
836
837
838
839
840 // -- wxAuiMultiNotebook class implementation --
841
842 BEGIN_EVENT_TABLE(wxAuiMultiNotebook, wxControl)
843 //EVT_ERASE_BACKGROUND(wxAuiMultiNotebook::OnEraseBackground)
844 //EVT_SIZE(wxAuiMultiNotebook::OnSize)
845 //EVT_LEFT_DOWN(wxAuiMultiNotebook::OnLeftDown)
846 EVT_CHILD_FOCUS(wxAuiMultiNotebook::OnChildFocus)
847 EVT_COMMAND_RANGE(10000, 10100,
848 wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING,
849 wxAuiMultiNotebook::OnTabClicked)
850 EVT_COMMAND_RANGE(10000, 10100,
851 wxEVT_COMMAND_AUINOTEBOOK_BEGIN_DRAG,
852 wxAuiMultiNotebook::OnTabBeginDrag)
853 EVT_COMMAND_RANGE(10000, 10100,
854 wxEVT_COMMAND_AUINOTEBOOK_END_DRAG,
855 wxAuiMultiNotebook::OnTabEndDrag)
856 EVT_COMMAND_RANGE(10000, 10100,
857 wxEVT_COMMAND_AUINOTEBOOK_DRAG_MOTION,
858 wxAuiMultiNotebook::OnTabDragMotion)
859 EVT_COMMAND_RANGE(10000, 10100,
860 wxEVT_COMMAND_AUINOTEBOOK_BUTTON,
861 wxAuiMultiNotebook::OnTabButton)
862 END_EVENT_TABLE()
863
864 wxAuiMultiNotebook::wxAuiMultiNotebook()
865 {
866 m_curpage = -1;
867 m_tab_id_counter = 10000;
868 m_dummy_wnd = NULL;
869 }
870
871 wxAuiMultiNotebook::wxAuiMultiNotebook(wxWindow *parent,
872 wxWindowID id,
873 const wxPoint& pos,
874 const wxSize& size,
875 long style) : wxControl(parent, id, pos, size, style)
876 {
877 InitNotebook();
878 }
879
880 bool wxAuiMultiNotebook::Create(wxWindow* parent,
881 wxWindowID id,
882 const wxPoint& pos,
883 const wxSize& size,
884 long style)
885 {
886 if (!wxControl::Create(parent, id, pos, size, style))
887 return false;
888
889 InitNotebook();
890
891 return true;
892 }
893
894 // InitNotebook() contains common initialization
895 // code called by all constructors
896 void wxAuiMultiNotebook::InitNotebook()
897 {
898 m_normal_font = *wxNORMAL_FONT;
899 m_selected_font = *wxNORMAL_FONT;
900 m_selected_font.SetWeight(wxBOLD);
901
902
903 m_tab_id_counter = 10000;
904
905 m_dummy_wnd = new wxWindow(this, -1, wxPoint(0,0), wxSize(0,0));
906 m_dummy_wnd->SetSize(200, 200);
907 m_dummy_wnd->Show(false);
908
909 m_mgr.SetManagedWindow(this);
910
911 m_mgr.AddPane(m_dummy_wnd,
912 wxPaneInfo().Name(wxT("dummy")).Bottom().Show(false));
913
914 m_mgr.Update();
915 }
916
917 wxAuiMultiNotebook::~wxAuiMultiNotebook()
918 {
919 m_mgr.UnInit();
920 }
921
922 bool wxAuiMultiNotebook::AddPage(wxWindow* page,
923 const wxString& caption,
924 bool select,
925 const wxBitmap& bitmap)
926 {
927 return InsertPage(GetPageCount(), page, caption, select, bitmap);
928 }
929
930 bool wxAuiMultiNotebook::InsertPage(size_t page_idx,
931 wxWindow* page,
932 const wxString& caption,
933 bool select,
934 const wxBitmap& bitmap)
935 {
936 wxAuiNotebookPage info;
937 info.window = page;
938 info.caption = caption;
939 info.bitmap = bitmap;
940 info.active = false;
941
942 // if there are currently no tabs, the first added
943 // tab must be active
944 if (m_tabs.GetPageCount() == 0)
945 info.active = true;
946
947 m_tabs.InsertPage(page, info, page_idx);
948
949 wxAuiTabCtrl* active_tabctrl = GetActiveTabCtrl();
950 if (page_idx >= active_tabctrl->GetPageCount())
951 active_tabctrl->AddPage(page, info);
952 else
953 active_tabctrl->InsertPage(page, info, page_idx);
954
955 DoSizing();
956 active_tabctrl->DoShowHide();
957
958 if (select)
959 {
960 int idx = m_tabs.GetIdxFromWindow(page);
961 wxASSERT_MSG(idx != -1, wxT("Invalid Page index returned on wxAuiMultiNotebook::InsertPage()"));
962
963 SetSelection(idx);
964 }
965
966 return true;
967 }
968
969
970 // DeletePage() removes a tab from the multi-notebook,
971 // and destroys the window as well
972 bool wxAuiMultiNotebook::DeletePage(size_t page_idx)
973 {
974 wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
975
976
977 // find out which onscreen tab ctrl owns this tab
978 wxAuiTabCtrl* ctrl;
979 int ctrl_idx;
980 if (!FindTab(wnd, &ctrl, &ctrl_idx))
981 return false;
982
983 // find a new page and set it as active
984 int new_idx = ctrl_idx+1;
985 if (new_idx >= (int)ctrl->GetPageCount())
986 new_idx = ctrl_idx-1;
987
988 if (new_idx >= 0 && new_idx < (int)ctrl->GetPageCount())
989 {
990 wxWindow* new_wnd = ctrl->GetWindowFromIdx(new_idx);
991 int main_idx = m_tabs.GetIdxFromWindow(new_wnd);
992 wxASSERT(main_idx != -1);
993 SetSelection(main_idx);
994 }
995 else
996 {
997 // set the active page to the first page that
998 // isn't the one being deleted
999 bool found = false;
1000 size_t i, page_count = m_tabs.GetPageCount();
1001 for (i = 0; i < page_count; ++i)
1002 {
1003 wxWindow* w = m_tabs.GetWindowFromIdx(i);
1004 if (wnd != w)
1005 {
1006 found = true;
1007 SetSelection(i);
1008 break;
1009 }
1010 }
1011
1012 if (!found)
1013 m_curpage = -1;
1014 }
1015
1016
1017 // remove the tab from main catalog
1018 if (!m_tabs.RemovePage(wnd))
1019 return false;
1020
1021 // remove the tab from the onscreen tab ctrl
1022 ctrl->RemovePage(wnd);
1023
1024 // actually destroy the window now
1025 if (wnd->IsKindOf(CLASSINFO(wxTabMDIChildFrame)))
1026 {
1027 // delete the child frame with pending delete, as is
1028 // customary with frame windows
1029 if (!wxPendingDelete.Member(wnd))
1030 wxPendingDelete.Append(wnd);
1031 }
1032 else
1033 {
1034 wnd->Destroy();
1035 }
1036
1037 RemoveEmptyTabFrames();
1038
1039 return true;
1040 }
1041
1042
1043
1044 // RemovePage() removes a tab from the multi-notebook,
1045 // but does not destroy the window
1046 bool wxAuiMultiNotebook::RemovePage(size_t page_idx)
1047 {
1048 // remove the tab from our own catalog
1049 wxWindow* wnd = m_tabs.GetWindowFromIdx(page_idx);
1050 if (!m_tabs.RemovePage(wnd))
1051 return false;
1052
1053 // remove the tab from the onscreen tab ctrl
1054 wxAuiTabCtrl* ctrl;
1055 int ctrl_idx;
1056 if (FindTab(wnd, &ctrl, &ctrl_idx))
1057 {
1058 ctrl->RemovePage(wnd);
1059 return true;
1060 }
1061
1062 return false;
1063 }
1064
1065 // SetPageText() changes the tab caption of the specified page
1066 bool wxAuiMultiNotebook::SetPageText(size_t page_idx, const wxString& text)
1067 {
1068 if (page_idx >= m_tabs.GetPageCount())
1069 return false;
1070
1071 // update our own tab catalog
1072 wxAuiNotebookPage& page_info = m_tabs.GetPage(page_idx);
1073 page_info.caption = text;
1074
1075 // update what's on screen
1076 wxAuiTabCtrl* ctrl;
1077 int ctrl_idx;
1078 if (FindTab(page_info.window, &ctrl, &ctrl_idx))
1079 {
1080 wxAuiNotebookPage& info = ctrl->GetPage(ctrl_idx);
1081 info.caption = text;
1082 ctrl->Refresh();
1083 }
1084
1085
1086 return true;
1087 }
1088
1089 // GetSelection() returns the index of the currently active page
1090 int wxAuiMultiNotebook::GetSelection() const
1091 {
1092 return m_curpage;
1093 }
1094
1095 // SetSelection() sets the currently active page
1096 size_t wxAuiMultiNotebook::SetSelection(size_t new_page)
1097 {
1098 wxWindow* wnd = m_tabs.GetWindowFromIdx(new_page);
1099 if (!wnd)
1100 return m_curpage;
1101
1102 wxAuiNotebookEvent evt(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGING, m_windowId);
1103 evt.SetSelection(new_page);
1104 evt.SetOldSelection(m_curpage);
1105 evt.SetEventObject(this);
1106 if (!GetEventHandler()->ProcessEvent(evt) || evt.IsAllowed())
1107 {
1108 // program allows the page change
1109 evt.SetEventType(wxEVT_COMMAND_AUINOTEBOOK_PAGE_CHANGED);
1110 (void)GetEventHandler()->ProcessEvent(evt);
1111
1112
1113
1114 wxAuiTabCtrl* ctrl;
1115 int ctrl_idx;
1116 if (FindTab(wnd, &ctrl, &ctrl_idx))
1117 {
1118 m_tabs.SetActivePage(wnd);
1119
1120 ctrl->SetActivePage(ctrl_idx);
1121 DoSizing();
1122 ctrl->DoShowHide();
1123
1124 int old_curpage = m_curpage;
1125 m_curpage = new_page;
1126
1127
1128 // set fonts
1129 wxPaneInfoArray& all_panes = m_mgr.GetAllPanes();
1130 size_t i, pane_count = all_panes.GetCount();
1131 for (i = 0; i < pane_count; ++i)
1132 {
1133 wxPaneInfo& pane = all_panes.Item(i);
1134 if (pane.name == wxT("dummy"))
1135 continue;
1136 wxAuiTabCtrl* tabctrl = ((wxTabFrame*)pane.window)->m_tabs;
1137 if (tabctrl != ctrl)
1138 tabctrl->SetSelectedFont(m_normal_font);
1139 else
1140 tabctrl->SetSelectedFont(m_selected_font);
1141 tabctrl->Refresh();
1142 }
1143
1144 wnd->SetFocus();
1145
1146 return old_curpage;
1147 }
1148 }
1149
1150 return m_curpage;
1151 }
1152
1153 // GetPageCount() returns the total number of
1154 // pages managed by the multi-notebook
1155 size_t wxAuiMultiNotebook::GetPageCount() const
1156 {
1157 return m_tabs.GetPageCount();
1158 }
1159
1160 // GetPage() returns the wxWindow pointer of the
1161 // specified page
1162 wxWindow* wxAuiMultiNotebook::GetPage(size_t page_idx) const
1163 {
1164 wxASSERT(page_idx < m_tabs.GetPageCount());
1165
1166 return m_tabs.GetWindowFromIdx(page_idx);
1167 }
1168
1169 // DoSizing() performs all sizing operations in each tab control
1170 void wxAuiMultiNotebook::DoSizing()
1171 {
1172 wxPaneInfoArray& all_panes = m_mgr.GetAllPanes();
1173 size_t i, pane_count = all_panes.GetCount();
1174 for (i = 0; i < pane_count; ++i)
1175 {
1176 if (all_panes.Item(i).name == wxT("dummy"))
1177 continue;
1178
1179 wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
1180 tabframe->DoSizing();
1181 }
1182 }
1183
1184 // GetActiveTabCtrl() returns the active tab control. It is
1185 // called to determine which control gets new windows being added
1186 wxAuiTabCtrl* wxAuiMultiNotebook::GetActiveTabCtrl()
1187 {
1188 if (m_curpage >= 0 && m_curpage < (int)m_tabs.GetPageCount())
1189 {
1190 wxAuiTabCtrl* ctrl;
1191 int idx;
1192
1193 // find the tab ctrl with the current page
1194 if (FindTab(m_tabs.GetPage(m_curpage).window,
1195 &ctrl, &idx))
1196 {
1197 return ctrl;
1198 }
1199 }
1200
1201 // no current page, just find the first tab ctrl
1202 wxPaneInfoArray& all_panes = m_mgr.GetAllPanes();
1203 size_t i, pane_count = all_panes.GetCount();
1204 for (i = 0; i < pane_count; ++i)
1205 {
1206 if (all_panes.Item(i).name == wxT("dummy"))
1207 continue;
1208
1209 wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
1210 return tabframe->m_tabs;
1211 }
1212
1213 // If there is no tabframe at all, create one
1214 wxTabFrame* tabframe = new wxTabFrame;
1215 tabframe->m_tabs = new wxAuiTabCtrl(this,
1216 m_tab_id_counter++,
1217 wxDefaultPosition,
1218 wxDefaultSize,
1219 wxNO_BORDER);
1220 m_mgr.AddPane(tabframe,
1221 wxPaneInfo().Center().CaptionVisible(false));
1222
1223 m_mgr.Update();
1224
1225 return tabframe->m_tabs;
1226 }
1227
1228 // FindTab() finds the tab control that currently contains the window as well
1229 // as the index of the window in the tab control. It returns true if the
1230 // window was found, otherwise false.
1231 bool wxAuiMultiNotebook::FindTab(wxWindow* page, wxAuiTabCtrl** ctrl, int* idx)
1232 {
1233 wxPaneInfoArray& all_panes = m_mgr.GetAllPanes();
1234 size_t i, pane_count = all_panes.GetCount();
1235 for (i = 0; i < pane_count; ++i)
1236 {
1237 if (all_panes.Item(i).name == wxT("dummy"))
1238 continue;
1239
1240 wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
1241
1242 int page_idx = tabframe->m_tabs->GetIdxFromWindow(page);
1243 if (page_idx != -1)
1244 {
1245 *ctrl = tabframe->m_tabs;
1246 *idx = page_idx;
1247 return true;
1248 }
1249 }
1250
1251 return false;
1252 }
1253
1254
1255 void wxAuiMultiNotebook::OnEraseBackground(wxEraseEvent&)
1256 {
1257 }
1258
1259 void wxAuiMultiNotebook::OnSize(wxSizeEvent&)
1260 {
1261 }
1262
1263 void wxAuiMultiNotebook::OnTabClicked(wxCommandEvent& command_evt)
1264 {
1265 wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt;
1266
1267 wxAuiTabCtrl* ctrl = (wxAuiTabCtrl*)evt.GetEventObject();
1268 wxASSERT(ctrl != NULL);
1269
1270 wxWindow* wnd = ctrl->GetWindowFromIdx(evt.GetSelection());
1271 wxASSERT(wnd != NULL);
1272
1273 int idx = m_tabs.GetIdxFromWindow(wnd);
1274 wxASSERT(idx != -1);
1275
1276 SetSelection(idx);
1277 }
1278
1279 void wxAuiMultiNotebook::OnTabBeginDrag(wxCommandEvent&)
1280 {
1281 }
1282
1283 void wxAuiMultiNotebook::OnTabDragMotion(wxCommandEvent& evt)
1284 {
1285 wxPoint screen_pt = ::wxGetMousePosition();
1286 wxPoint client_pt = ScreenToClient(screen_pt);
1287 wxPoint zero(0,0);
1288
1289 wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject();
1290
1291 wxAuiTabCtrl* tab_ctrl = GetTabCtrlFromPoint(client_pt);
1292 if (tab_ctrl == src_tabs)
1293 {
1294 // inner-tabctrl dragging is not yet implemented
1295 m_mgr.HideHint();
1296 return;
1297 }
1298
1299 if (tab_ctrl)
1300 {
1301 wxRect hint_rect = tab_ctrl->GetRect();
1302 ClientToScreen(&hint_rect.x, &hint_rect.y);
1303 m_mgr.ShowHint(hint_rect);
1304 }
1305 else
1306 {
1307 m_mgr.DrawHintRect(m_dummy_wnd, client_pt, zero);
1308 }
1309 }
1310
1311
1312
1313 void wxAuiMultiNotebook::OnTabEndDrag(wxCommandEvent& command_evt)
1314 {
1315 wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt;
1316
1317 m_mgr.HideHint();
1318
1319
1320 // get the mouse position, which will be used to determine the drop point
1321 wxPoint mouse_screen_pt = ::wxGetMousePosition();
1322 wxPoint mouse_client_pt = ScreenToClient(mouse_screen_pt);
1323
1324
1325 // the src tab control is the control that fired this event
1326 wxAuiTabCtrl* src_tabs = (wxAuiTabCtrl*)evt.GetEventObject();
1327 wxAuiTabCtrl* dest_tabs = NULL;
1328
1329
1330 // If the pointer is in an existing tab frame, do a tab insert
1331 wxWindow* hit_wnd = ::wxFindWindowAtPoint(mouse_screen_pt);
1332 wxTabFrame* tab_frame = (wxTabFrame*)GetTabFrameFromTabCtrl(hit_wnd);
1333 if (tab_frame)
1334 {
1335 dest_tabs = tab_frame->m_tabs;
1336
1337 if (dest_tabs == src_tabs)
1338 return;
1339 }
1340 else
1341 {
1342 // If there is no tabframe at all, create one
1343 wxTabFrame* new_tabs = new wxTabFrame;
1344 new_tabs->m_tabs = new wxAuiTabCtrl(this,
1345 m_tab_id_counter++,
1346 wxDefaultPosition,
1347 wxDefaultSize,
1348 wxNO_BORDER);
1349 m_mgr.AddPane(new_tabs,
1350 wxPaneInfo().Bottom().CaptionVisible(false),
1351 mouse_client_pt);
1352 m_mgr.Update();
1353 dest_tabs = new_tabs->m_tabs;
1354 }
1355
1356
1357
1358 // remove the page from the source tabs
1359 wxAuiNotebookPage page_info = src_tabs->GetPage(evt.GetSelection());
1360 page_info.active = false;
1361 src_tabs->RemovePage(page_info.window);
1362 if (src_tabs->GetPageCount() > 0)
1363 {
1364 src_tabs->SetActivePage((size_t)0);
1365 src_tabs->DoShowHide();
1366 src_tabs->Refresh();
1367 }
1368
1369
1370
1371 // add the page to the destination tabs
1372 dest_tabs->AddPage(page_info.window, page_info);
1373
1374 if (src_tabs->GetPageCount() == 0)
1375 {
1376 RemoveEmptyTabFrames();
1377 }
1378
1379 DoSizing();
1380 dest_tabs->DoShowHide();
1381 dest_tabs->Refresh();
1382
1383 SetSelection(m_tabs.GetIdxFromWindow(page_info.window));
1384 }
1385
1386 wxAuiTabCtrl* wxAuiMultiNotebook::GetTabCtrlFromPoint(const wxPoint& pt)
1387 {
1388 // if we've just removed the last tab from the source
1389 // tab set, the remove the tab control completely
1390 wxPaneInfoArray& all_panes = m_mgr.GetAllPanes();
1391 size_t i, pane_count = all_panes.GetCount();
1392 for (i = 0; i < pane_count; ++i)
1393 {
1394 if (all_panes.Item(i).name == wxT("dummy"))
1395 continue;
1396
1397 wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
1398 if (tabframe->m_tab_rect.Inside(pt))
1399 return tabframe->m_tabs;
1400 }
1401
1402 return NULL;
1403 }
1404
1405 wxWindow* wxAuiMultiNotebook::GetTabFrameFromTabCtrl(wxWindow* tab_ctrl)
1406 {
1407 // if we've just removed the last tab from the source
1408 // tab set, the remove the tab control completely
1409 wxPaneInfoArray& all_panes = m_mgr.GetAllPanes();
1410 size_t i, pane_count = all_panes.GetCount();
1411 for (i = 0; i < pane_count; ++i)
1412 {
1413 if (all_panes.Item(i).name == wxT("dummy"))
1414 continue;
1415
1416 wxTabFrame* tabframe = (wxTabFrame*)all_panes.Item(i).window;
1417 if (tabframe->m_tabs == tab_ctrl)
1418 {
1419 return tabframe;
1420 }
1421 }
1422
1423 return NULL;
1424 }
1425
1426 void wxAuiMultiNotebook::RemoveEmptyTabFrames()
1427 {
1428 bool must_update = false;
1429
1430 // if we've just removed the last tab from the source
1431 // tab set, the remove the tab control completely
1432 wxPaneInfoArray all_panes = m_mgr.GetAllPanes();
1433 size_t i, pane_count = all_panes.GetCount();
1434 for (i = 0; i < pane_count; ++i)
1435 {
1436 if (all_panes.Item(i).name == wxT("dummy"))
1437 continue;
1438
1439 wxTabFrame* tab_frame = (wxTabFrame*)all_panes.Item(i).window;
1440 if (tab_frame->m_tabs->GetPageCount() == 0)
1441 {
1442 m_mgr.DetachPane(tab_frame);
1443
1444 // use pending delete because sometimes during
1445 // window closing, refreshs are pending
1446 if (!wxPendingDelete.Member(tab_frame->m_tabs))
1447 wxPendingDelete.Append(tab_frame->m_tabs);
1448 //tab_frame->m_tabs->Destroy();
1449
1450 delete tab_frame;
1451 must_update = true;
1452 }
1453 }
1454
1455
1456 // check to see if there is still a center pane;
1457 // if there isn't, make a frame the center pane
1458 wxPaneInfoArray panes = m_mgr.GetAllPanes();
1459 pane_count = panes.GetCount();
1460 wxWindow* first_good = NULL;
1461 bool center_found = false;
1462 for (i = 0; i < pane_count; ++i)
1463 {
1464 if (panes.Item(i).name == wxT("dummy"))
1465 continue;
1466 if (panes.Item(i).dock_direction == wxAUI_DOCK_CENTRE)
1467 center_found = true;
1468 if (!first_good)
1469 first_good = panes.Item(i).window;
1470 }
1471
1472 if (!center_found && first_good)
1473 {
1474 m_mgr.GetPane(first_good).Centre();
1475 must_update = true;
1476 }
1477
1478 m_mgr.Update();
1479 }
1480
1481 void wxAuiMultiNotebook::OnChildFocus(wxChildFocusEvent& evt)
1482 {
1483 int idx = m_tabs.GetIdxFromWindow(evt.GetWindow());
1484 if (idx != -1 && idx != m_curpage)
1485 {
1486 SetSelection(idx);
1487 }
1488 }
1489
1490
1491 void wxAuiMultiNotebook::OnTabButton(wxCommandEvent& command_evt)
1492 {
1493 wxAuiNotebookEvent& evt = (wxAuiNotebookEvent&)command_evt;
1494 wxAuiTabCtrl* tabs = (wxAuiTabCtrl*)evt.GetEventObject();
1495
1496 int button_id = evt.GetInt();
1497
1498 if (button_id == wxAuiButtonClose)
1499 {
1500 int selection = tabs->GetActivePage();
1501
1502 if (selection != -1)
1503 {
1504 wxWindow* close_wnd = tabs->GetWindowFromIdx(selection);
1505
1506 if (close_wnd->IsKindOf(CLASSINFO(wxTabMDIChildFrame)))
1507 {
1508 close_wnd->Close();
1509 }
1510 else
1511 {
1512 int main_idx = m_tabs.GetIdxFromWindow(close_wnd);
1513 DeletePage(main_idx);
1514 }
1515 }
1516 }
1517 }
1518
1519
1520
1521
1522 #endif // wxUSE_AUI