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