1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/aui/framemanager.cpp 
   3 // Purpose:     wxaui: wx advanced user interface - docking window manager 
   4 // Author:      Benjamin I. Williams 
   8 // Copyright:   (C) Copyright 2005-2006, Kirix Corporation, All Rights Reserved 
   9 // Licence:     wxWindows Library Licence, Version 3.1 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #include "wx/wxprec.h" 
  28 #include "wx/aui/framemanager.h" 
  29 #include "wx/aui/dockart.h" 
  30 #include "wx/aui/floatpane.h" 
  31 #include "wx/aui/tabmdi.h" 
  35     #include "wx/settings.h" 
  37     #include "wx/dcclient.h" 
  38     #include "wx/dcscreen.h" 
  39     #include "wx/toolbar.h" 
  44 WX_CHECK_BUILD_OPTIONS("wxAUI") 
  46 #include "wx/arrimpl.cpp" 
  47 WX_DECLARE_OBJARRAY(wxRect
, wxAuiRectArray
); 
  48 WX_DEFINE_OBJARRAY(wxAuiRectArray
) 
  49 WX_DEFINE_OBJARRAY(wxAuiDockUIPartArray
) 
  50 WX_DEFINE_OBJARRAY(wxAuiDockInfoArray
) 
  51 WX_DEFINE_OBJARRAY(wxAuiPaneButtonArray
) 
  52 WX_DEFINE_OBJARRAY(wxAuiPaneInfoArray
) 
  54 wxAuiPaneInfo wxAuiNullPaneInfo
; 
  55 wxAuiDockInfo wxAuiNullDockInfo
; 
  56 DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_BUTTON
) 
  57 DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_CLOSE
) 
  58 DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_MAXIMIZE
) 
  59 DEFINE_EVENT_TYPE(wxEVT_AUI_PANE_RESTORE
) 
  60 DEFINE_EVENT_TYPE(wxEVT_AUI_RENDER
) 
  61 DEFINE_EVENT_TYPE(wxEVT_AUI_FIND_MANAGER
) 
  64     // a few defines to avoid nameclashes 
  65     #define __MAC_OS_X_MEMORY_MANAGER_CLEAN__ 1 
  67     #include "wx/osx/private.h" 
  71     #include "wx/msw/wrapwin.h" 
  72     #include "wx/msw/private.h" 
  73     #include "wx/msw/dc.h" 
  76 IMPLEMENT_DYNAMIC_CLASS(wxAuiManagerEvent
, wxEvent
) 
  77 IMPLEMENT_CLASS(wxAuiManager
, wxEvtHandler
) 
  81 const int auiToolBarLayer 
= 10; 
  86 class wxPseudoTransparentFrame 
: public wxFrame
 
  89     wxPseudoTransparentFrame(wxWindow
* parent 
= NULL
, 
  90                 wxWindowID id 
= wxID_ANY
, 
  91                 const wxString
& title 
= wxEmptyString
, 
  92                 const wxPoint
& pos 
= wxDefaultPosition
, 
  93                 const wxSize
& size 
= wxDefaultSize
, 
  94                 long style 
= wxDEFAULT_FRAME_STYLE
, 
  95                 const wxString 
&name 
= wxT("frame")) 
  96                     : wxFrame(parent
, id
, title
, pos
, size
, style 
| wxFRAME_SHAPED
, name
) 
  98         SetBackgroundStyle(wxBG_STYLE_CUSTOM
); 
 105         m_CanSetShape 
= false; // have to wait for window create event on GTK 
 107         m_CanSetShape 
= true; 
 109         m_Region 
= wxRegion(0, 0, 0, 0); 
 113     virtual bool SetTransparent(wxByte alpha
) 
 117             int w
=100; // some defaults 
 119             GetClientSize(&w
, &h
); 
 125 //            m_Region.Union(0, 0, 1, m_MaxWidth); 
 128                 for (int y
=0; y
<m_MaxHeight
; y
++) 
 130                     // Reverse the order of the bottom 4 bits 
 131                     int j
=((y
&8)?1:0)|((y
&4)?2:0)|((y
&2)?4:0)|((y
&1)?8:0); 
 132                     if ((j
*16+8)<m_Amount
) 
 133                         m_Region
.Union(0, y
, m_MaxWidth
, 1); 
 142     void OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
 146         if (m_Region
.IsEmpty()) 
 150         dc
.SetBrush(wxColour(128, 192, 255)); 
 152         dc
.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION
)); 
 154         dc
.SetPen(*wxTRANSPARENT_PEN
); 
 156         wxRegionIterator 
upd(GetUpdateRegion()); // get the update rect list 
 160             wxRect 
rect(upd
.GetRect()); 
 161             dc
.DrawRectangle(rect
.x
, rect
.y
, rect
.width
, rect
.height
); 
 168     void OnWindowCreate(wxWindowCreateEvent
& WXUNUSED(event
)) 
 175     void OnSize(wxSizeEvent
& event
) 
 177         // We sometimes get surplus size events 
 178         if ((event
.GetSize().GetWidth() == m_lastWidth
) && 
 179             (event
.GetSize().GetHeight() == m_lastHeight
)) 
 184         m_lastWidth 
= event
.GetSize().GetWidth(); 
 185         m_lastHeight 
= event
.GetSize().GetHeight(); 
 187         SetTransparent(m_Amount
); 
 188         m_Region
.Intersect(0, 0, event
.GetSize().GetWidth(), 
 189                            event
.GetSize().GetHeight()); 
 200     int m_lastWidth
,m_lastHeight
; 
 204     DECLARE_DYNAMIC_CLASS(wxPseudoTransparentFrame
) 
 205     DECLARE_EVENT_TABLE() 
 209 IMPLEMENT_DYNAMIC_CLASS(wxPseudoTransparentFrame
, wxFrame
) 
 211 BEGIN_EVENT_TABLE(wxPseudoTransparentFrame
, wxFrame
) 
 212     EVT_PAINT(wxPseudoTransparentFrame::OnPaint
) 
 213     EVT_SIZE(wxPseudoTransparentFrame::OnSize
) 
 215     EVT_WINDOW_CREATE(wxPseudoTransparentFrame::OnWindowCreate
) 
 226 gtk_pseudo_window_realized_callback( GtkWidget 
*m_widget
, void *WXUNUSED(win
) ) 
 228         wxSize disp 
= wxGetDisplaySize(); 
 231         for (int y
=0; y
<disp
.y
; y
++) 
 233                     // Reverse the order of the bottom 4 bits 
 234                     int j
=((y
&8)?1:0)|((y
&4)?2:0)|((y
&2)?4:0)|((y
&1)?8:0); 
 236                         region
.Union(0, y
, disp
.x
, 1); 
 238         gdk_window_shape_combine_region(m_widget
->window
, region
.GetRegion(), 0, 0); 
 242 class wxPseudoTransparentFrame
: public wxFrame
 
 245     wxPseudoTransparentFrame(wxWindow
* parent 
= NULL
, 
 246                 wxWindowID id 
= wxID_ANY
, 
 247                 const wxString
& title 
= wxEmptyString
, 
 248                 const wxPoint
& pos 
= wxDefaultPosition
, 
 249                 const wxSize
& size 
= wxDefaultSize
, 
 250                 long style 
= wxDEFAULT_FRAME_STYLE
, 
 251                 const wxString 
&name 
= wxT("frame")) 
 253          if (!CreateBase( parent
, id
, pos
, size
, style
, wxDefaultValidator
, name 
)) 
 258         m_widget 
= gtk_window_new( GTK_WINDOW_POPUP 
); 
 260         g_signal_connect( m_widget
, "realize", 
 261                       G_CALLBACK (gtk_pseudo_window_realized_callback
), this ); 
 265         col
.green 
= 192 * 256; 
 266         col
.blue 
= 255 * 256; 
 267         gtk_widget_modify_bg( m_widget
, GTK_STATE_NORMAL
, &col 
); 
 270     bool SetTransparent(wxByte 
WXUNUSED(alpha
)) 
 276     DECLARE_DYNAMIC_CLASS(wxPseudoTransparentFrame
) 
 279 IMPLEMENT_DYNAMIC_CLASS(wxPseudoTransparentFrame
, wxFrame
) 
 286 // -- static utility functions -- 
 288 static wxBitmap 
wxPaneCreateStippleBitmap() 
 290     unsigned char data
[] = { 0,0,0,192,192,192, 192,192,192,0,0,0 }; 
 291     wxImage 
img(2,2,data
,true); 
 292     return wxBitmap(img
); 
 295 static void DrawResizeHint(wxDC
& dc
, const wxRect
& rect
) 
 297     wxBitmap stipple 
= wxPaneCreateStippleBitmap(); 
 298     wxBrush 
brush(stipple
); 
 301     wxMSWDCImpl 
*impl 
= (wxMSWDCImpl
*) dc
.GetImpl(); 
 302     PatBlt(GetHdcOf(*impl
), rect
.GetX(), rect
.GetY(), rect
.GetWidth(), rect
.GetHeight(), PATINVERT
); 
 304     dc
.SetPen(*wxTRANSPARENT_PEN
); 
 306     dc
.SetLogicalFunction(wxXOR
); 
 307     dc
.DrawRectangle(rect
); 
 313 // CopyDocksAndPanes() - this utility function creates copies of 
 314 // the dock and pane info.  wxAuiDockInfo's usually contain pointers 
 315 // to wxAuiPaneInfo classes, thus this function is necessary to reliably 
 316 // reconstruct that relationship in the new dock info and pane info arrays 
 318 static void CopyDocksAndPanes(wxAuiDockInfoArray
& dest_docks
, 
 319                               wxAuiPaneInfoArray
& dest_panes
, 
 320                               const wxAuiDockInfoArray
& src_docks
, 
 321                               const wxAuiPaneInfoArray
& src_panes
) 
 323     dest_docks 
= src_docks
; 
 324     dest_panes 
= src_panes
; 
 325     int i
, j
, k
, dock_count
, pc1
, pc2
; 
 326     for (i 
= 0, dock_count 
= dest_docks
.GetCount(); i 
< dock_count
; ++i
) 
 328         wxAuiDockInfo
& dock 
= dest_docks
.Item(i
); 
 329         for (j 
= 0, pc1 
= dock
.panes
.GetCount(); j 
< pc1
; ++j
) 
 330             for (k 
= 0, pc2 
= src_panes
.GetCount(); k 
< pc2
; ++k
) 
 331                 if (dock
.panes
.Item(j
) == &src_panes
.Item(k
)) 
 332                     dock
.panes
.Item(j
) = &dest_panes
.Item(k
); 
 336 // GetMaxLayer() is an internal function which returns 
 337 // the highest layer inside the specified dock 
 338 static int GetMaxLayer(const wxAuiDockInfoArray
& docks
, 
 341     int i
, dock_count
, max_layer 
= 0; 
 342     for (i 
= 0, dock_count 
= docks
.GetCount(); i 
< dock_count
; ++i
) 
 344         wxAuiDockInfo
& dock 
= docks
.Item(i
); 
 345         if (dock
.dock_direction 
== dock_direction 
&& 
 346             dock
.dock_layer 
> max_layer 
&& !dock
.fixed
) 
 347                 max_layer 
= dock
.dock_layer
; 
 353 // GetMaxRow() is an internal function which returns 
 354 // the highest layer inside the specified dock 
 355 static int GetMaxRow(const wxAuiPaneInfoArray
& panes
, int direction
, int layer
) 
 357     int i
, pane_count
, max_row 
= 0; 
 358     for (i 
= 0, pane_count 
= panes
.GetCount(); i 
< pane_count
; ++i
) 
 360         wxAuiPaneInfo
& pane 
= panes
.Item(i
); 
 361         if (pane
.dock_direction 
== direction 
&& 
 362             pane
.dock_layer 
== layer 
&& 
 363             pane
.dock_row 
> max_row
) 
 364                 max_row 
= pane
.dock_row
; 
 371 // DoInsertDockLayer() is an internal function that inserts a new dock 
 372 // layer by incrementing all existing dock layer values by one 
 373 static void DoInsertDockLayer(wxAuiPaneInfoArray
& panes
, 
 378     for (i 
= 0, pane_count 
= panes
.GetCount(); i 
< pane_count
; ++i
) 
 380         wxAuiPaneInfo
& pane 
= panes
.Item(i
); 
 381         if (!pane
.IsFloating() && 
 382             pane
.dock_direction 
== dock_direction 
&& 
 383             pane
.dock_layer 
>= dock_layer
) 
 388 // DoInsertDockLayer() is an internal function that inserts a new dock 
 389 // row by incrementing all existing dock row values by one 
 390 static void DoInsertDockRow(wxAuiPaneInfoArray
& panes
, 
 396     for (i 
= 0, pane_count 
= panes
.GetCount(); i 
< pane_count
; ++i
) 
 398         wxAuiPaneInfo
& pane 
= panes
.Item(i
); 
 399         if (!pane
.IsFloating() && 
 400             pane
.dock_direction 
== dock_direction 
&& 
 401             pane
.dock_layer 
== dock_layer 
&& 
 402             pane
.dock_row 
>= dock_row
) 
 407 // DoInsertDockLayer() is an internal function that inserts a space for 
 408 // another dock pane by incrementing all existing dock row values by one 
 409 static void DoInsertPane(wxAuiPaneInfoArray
& panes
, 
 416     for (i 
= 0, pane_count 
= panes
.GetCount(); i 
< pane_count
; ++i
) 
 418         wxAuiPaneInfo
& pane 
= panes
.Item(i
); 
 419         if (!pane
.IsFloating() && 
 420             pane
.dock_direction 
== dock_direction 
&& 
 421             pane
.dock_layer 
== dock_layer 
&& 
 422             pane
.dock_row 
== dock_row 
&& 
 423             pane
.dock_pos 
>= dock_pos
) 
 428 // FindDocks() is an internal function that returns a list of docks which meet 
 429 // the specified conditions in the parameters and returns a sorted array 
 430 // (sorted by layer and then row) 
 431 static void FindDocks(wxAuiDockInfoArray
& docks
, 
 435                       wxAuiDockInfoPtrArray
& arr
) 
 437     int begin_layer 
= dock_layer
; 
 438     int end_layer 
= dock_layer
; 
 439     int begin_row 
= dock_row
; 
 440     int end_row 
= dock_row
; 
 441     int dock_count 
= docks
.GetCount(); 
 442     int layer
, row
, i
, max_row 
= 0, max_layer 
= 0; 
 444     // discover the maximum dock layer and the max row 
 445     for (i 
= 0; i 
< dock_count
; ++i
) 
 447         max_row 
= wxMax(max_row
, docks
.Item(i
).dock_row
); 
 448         max_layer 
= wxMax(max_layer
, docks
.Item(i
).dock_layer
); 
 451     // if no dock layer was specified, search all dock layers 
 452     if (dock_layer 
== -1) 
 455         end_layer 
= max_layer
; 
 458     // if no dock row was specified, search all dock row 
 467     for (layer 
= begin_layer
; layer 
<= end_layer
; ++layer
) 
 468         for (row 
= begin_row
; row 
<= end_row
; ++row
) 
 469             for (i 
= 0; i 
< dock_count
; ++i
) 
 471                 wxAuiDockInfo
& d 
= docks
.Item(i
); 
 472                 if (dock_direction 
== -1 || dock_direction 
== d
.dock_direction
) 
 474                     if (d
.dock_layer 
== layer 
&& d
.dock_row 
== row
) 
 480 // FindPaneInDock() looks up a specified window pointer inside a dock. 
 481 // If found, the corresponding wxAuiPaneInfo pointer is returned, otherwise NULL. 
 482 static wxAuiPaneInfo
* FindPaneInDock(const wxAuiDockInfo
& dock
, wxWindow
* window
) 
 484     int i
, count 
= dock
.panes
.GetCount(); 
 485     for (i 
= 0; i 
< count
; ++i
) 
 487         wxAuiPaneInfo
* p 
= dock
.panes
.Item(i
); 
 488         if (p
->window 
== window
) 
 494 // RemovePaneFromDocks() removes a pane window from all docks 
 495 // with a possible exception specified by parameter "ex_cept" 
 496 static void RemovePaneFromDocks(wxAuiDockInfoArray
& docks
, 
 498                                 wxAuiDockInfo
* ex_cept  
= NULL  
) 
 501     for (i 
= 0, dock_count 
= docks
.GetCount(); i 
< dock_count
; ++i
) 
 503         wxAuiDockInfo
& d 
= docks
.Item(i
); 
 506         wxAuiPaneInfo
* pi 
= FindPaneInDock(d
, pane
.window
); 
 513 // This function works fine, and may be used in the future 
 515 // RenumberDockRows() takes a dock and assigns sequential numbers 
 516 // to existing rows.  Basically it takes out the gaps; so if a 
 517 // dock has rows with numbers 0,2,5, they will become 0,1,2 
 518 static void RenumberDockRows(wxAuiDockInfoPtrArray& docks) 
 521     for (i = 0, dock_count = docks.GetCount(); i < dock_count; ++i) 
 523         wxAuiDockInfo& dock = *docks.Item(i); 
 527         for (j = 0, pane_count = dock.panes.GetCount(); j < pane_count; ++j) 
 528             dock.panes.Item(j)->dock_row = i; 
 534 // SetActivePane() sets the active pane, as well as cycles through 
 535 // every other pane and makes sure that all others' active flags 
 537 static void SetActivePane(wxAuiPaneInfoArray
& panes
, wxWindow
* active_pane
) 
 540     for (i 
= 0, pane_count 
= panes
.GetCount(); i 
< pane_count
; ++i
) 
 542         wxAuiPaneInfo
& pane 
= panes
.Item(i
); 
 543         pane
.state 
&= ~wxAuiPaneInfo::optionActive
; 
 544         if (pane
.window 
== active_pane
) 
 545             pane
.state 
|= wxAuiPaneInfo::optionActive
; 
 550 // this function is used to sort panes by dock position 
 551 static int PaneSortFunc(wxAuiPaneInfo
** p1
, wxAuiPaneInfo
** p2
) 
 553     return ((*p1
)->dock_pos 
< (*p2
)->dock_pos
) ? -1 : 1; 
 557 // -- wxAuiManager class implementation -- 
 560 BEGIN_EVENT_TABLE(wxAuiManager
, wxEvtHandler
) 
 561     EVT_AUI_PANE_BUTTON(wxAuiManager::OnPaneButton
) 
 562     EVT_AUI_RENDER(wxAuiManager::OnRender
) 
 563     EVT_PAINT(wxAuiManager::OnPaint
) 
 564     EVT_ERASE_BACKGROUND(wxAuiManager::OnEraseBackground
) 
 565     EVT_SIZE(wxAuiManager::OnSize
) 
 566     EVT_SET_CURSOR(wxAuiManager::OnSetCursor
) 
 567     EVT_LEFT_DOWN(wxAuiManager::OnLeftDown
) 
 568     EVT_LEFT_UP(wxAuiManager::OnLeftUp
) 
 569     EVT_MOTION(wxAuiManager::OnMotion
) 
 570     EVT_LEAVE_WINDOW(wxAuiManager::OnLeaveWindow
) 
 571     EVT_CHILD_FOCUS(wxAuiManager::OnChildFocus
) 
 572     EVT_AUI_FIND_MANAGER(wxAuiManager::OnFindManager
) 
 573     EVT_TIMER(101, wxAuiManager::OnHintFadeTimer
) 
 577 wxAuiManager::wxAuiManager(wxWindow
* managed_wnd
, unsigned int flags
) 
 579     m_action 
= actionNone
; 
 580     m_last_mouse_move 
= wxPoint(); 
 581     m_hover_button 
= NULL
; 
 582     m_art 
= new wxAuiDefaultDockArt
; 
 586     m_has_maximized 
= false; 
 588     m_dock_constraint_x 
= 0.3; 
 589     m_dock_constraint_y 
= 0.3; 
 594         SetManagedWindow(managed_wnd
); 
 598 wxAuiManager::~wxAuiManager() 
 600     // NOTE: It's possible that the windows have already been destroyed by the 
 601     // time this dtor is called, so this loop can result in memory access via 
 602     // invalid pointers, resulting in a crash.  So it will be disabled while 
 603     // waiting for a better solution. 
 605     for ( size_t i 
= 0; i 
< m_panes
.size(); i
++ ) 
 607         wxAuiPaneInfo
& pinfo 
= m_panes
[i
]; 
 608         if (pinfo
.window 
&& !pinfo
.window
->GetParent()) 
 616 // creates a floating frame for the windows 
 617 wxAuiFloatingFrame
* wxAuiManager::CreateFloatingFrame(wxWindow
* parent
, 
 618                                                       const wxAuiPaneInfo
& pane_info
) 
 620     return new wxAuiFloatingFrame(parent
, this, pane_info
); 
 623 bool wxAuiManager::CanDockPanel(const wxAuiPaneInfo 
& WXUNUSED(p
)) 
 625     // if a key modifier is pressed while dragging the frame, 
 626     // don't dock the window 
 627     return !(wxGetKeyState(WXK_CONTROL
) || wxGetKeyState(WXK_ALT
)); 
 630 // GetPane() looks up a wxAuiPaneInfo structure based 
 631 // on the supplied window pointer.  Upon failure, GetPane() 
 632 // returns an empty wxAuiPaneInfo, a condition which can be checked 
 633 // by calling wxAuiPaneInfo::IsOk(). 
 635 // The pane info's structure may then be modified.  Once a pane's 
 636 // info is modified, wxAuiManager::Update() must be called to 
 637 // realize the changes in the UI. 
 639 wxAuiPaneInfo
& wxAuiManager::GetPane(wxWindow
* window
) 
 642     for (i 
= 0, pane_count 
= m_panes
.GetCount(); i 
< pane_count
; ++i
) 
 644         wxAuiPaneInfo
& p 
= m_panes
.Item(i
); 
 645         if (p
.window 
== window
) 
 648     return wxAuiNullPaneInfo
; 
 651 // this version of GetPane() looks up a pane based on a 
 652 // 'pane name', see above comment for more info 
 653 wxAuiPaneInfo
& wxAuiManager::GetPane(const wxString
& name
) 
 656     for (i 
= 0, pane_count 
= m_panes
.GetCount(); i 
< pane_count
; ++i
) 
 658         wxAuiPaneInfo
& p 
= m_panes
.Item(i
); 
 662     return wxAuiNullPaneInfo
; 
 665 // GetAllPanes() returns a reference to all the pane info structures 
 666 wxAuiPaneInfoArray
& wxAuiManager::GetAllPanes() 
 671 // HitTest() is an internal function which determines 
 672 // which UI item the specified coordinates are over 
 673 // (x,y) specify a position in client coordinates 
 674 wxAuiDockUIPart
* wxAuiManager::HitTest(int x
, int y
) 
 676     wxAuiDockUIPart
* result 
= NULL
; 
 679     for (i 
= 0, part_count 
= m_uiparts
.GetCount(); i 
< part_count
; ++i
) 
 681         wxAuiDockUIPart
* item 
= &m_uiparts
.Item(i
); 
 683         // we are not interested in typeDock, because this space 
 684         // isn't used to draw anything, just for measurements; 
 685         // besides, the entire dock area is covered with other 
 686         // rectangles, which we are interested in. 
 687         if (item
->type 
== wxAuiDockUIPart::typeDock
) 
 690         // if we already have a hit on a more specific item, we are not 
 691         // interested in a pane hit.  If, however, we don't already have 
 692         // a hit, returning a pane hit is necessary for some operations 
 693         if ((item
->type 
== wxAuiDockUIPart::typePane 
|| 
 694             item
->type 
== wxAuiDockUIPart::typePaneBorder
) && result
) 
 697         // if the point is inside the rectangle, we have a hit 
 698         if (item
->rect
.Contains(x
,y
)) 
 706 // SetFlags() and GetFlags() allow the owner to set various 
 707 // options which are global to wxAuiManager 
 708 void wxAuiManager::SetFlags(unsigned int flags
) 
 710     // find out if we have to call UpdateHintWindowConfig() 
 711     bool update_hint_wnd 
= false; 
 712     unsigned int hint_mask 
= wxAUI_MGR_TRANSPARENT_HINT 
| 
 713                              wxAUI_MGR_VENETIAN_BLINDS_HINT 
| 
 714                              wxAUI_MGR_RECTANGLE_HINT
; 
 715     if ((flags 
& hint_mask
) != (m_flags 
& hint_mask
)) 
 716         update_hint_wnd 
= true; 
 724         UpdateHintWindowConfig(); 
 728 unsigned int wxAuiManager::GetFlags() const 
 734 // don't use these anymore as they are deprecated 
 735 // use Set/GetManagedFrame() instead 
 736 void wxAuiManager::SetFrame(wxFrame
* frame
) 
 738     SetManagedWindow((wxWindow
*)frame
); 
 741 wxFrame
* wxAuiManager::GetFrame() const 
 743     return (wxFrame
*)m_frame
; 
 747 // this function will return the aui manager for a given 
 748 // window.  The |window| parameter should be any child window 
 749 // or grand-child window (and so on) of the frame/window 
 750 // managed by wxAuiManager.  The |window| parameter does not 
 751 // need to be managed by the manager itself. 
 752 wxAuiManager
* wxAuiManager::GetManager(wxWindow
* window
) 
 754     wxAuiManagerEvent 
evt(wxEVT_AUI_FIND_MANAGER
); 
 755     evt
.SetManager(NULL
); 
 756     evt
.ResumePropagation(wxEVENT_PROPAGATE_MAX
); 
 757     if (!window
->ProcessEvent(evt
)) 
 760     return evt
.GetManager(); 
 764 void wxAuiManager::UpdateHintWindowConfig() 
 766     // find out if the the system can do transparent frames 
 767     bool can_do_transparent 
= false; 
 769     wxWindow
* w 
= m_frame
; 
 772         if (w
->IsKindOf(CLASSINFO(wxFrame
))) 
 774             wxFrame
* f 
= static_cast<wxFrame
*>(w
); 
 775             can_do_transparent 
= f
->CanSetTransparent(); 
 783     // if there is an existing hint window, delete it 
 786         m_hint_wnd
->Destroy(); 
 793     if ((m_flags 
& wxAUI_MGR_TRANSPARENT_HINT
) && can_do_transparent
) 
 795         // Make a window to use for a transparent hint 
 796         #if defined(__WXMSW__) || defined(__WXGTK__) 
 797             m_hint_wnd 
= new wxFrame(m_frame
, wxID_ANY
, wxEmptyString
, 
 798                                      wxDefaultPosition
, wxSize(1,1), 
 799                                          wxFRAME_TOOL_WINDOW 
| 
 800                                          wxFRAME_FLOAT_ON_PARENT 
| 
 804             m_hint_wnd
->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION
)); 
 805         #elif defined(__WXMAC__) 
 806             // Using a miniframe with float and tool styles keeps the parent 
 807             // frame activated and highlighted as such... 
 808             m_hint_wnd 
= new wxMiniFrame(m_frame
, wxID_ANY
, wxEmptyString
, 
 809                                          wxDefaultPosition
, wxSize(1,1), 
 810                                          wxFRAME_FLOAT_ON_PARENT
 
 811                                          | wxFRAME_TOOL_WINDOW 
); 
 813             // Can't set the bg colour of a Frame in wxMac 
 814             wxPanel
* p 
= new wxPanel(m_hint_wnd
); 
 816             // The default wxSYS_COLOUR_ACTIVECAPTION colour is a light silver 
 817             // color that is really hard to see, especially transparent. 
 818             // Until a better system color is decided upon we'll just use 
 820             p
->SetBackgroundColour(*wxBLUE
); 
 826         if ((m_flags 
& wxAUI_MGR_TRANSPARENT_HINT
) != 0 || 
 827             (m_flags 
& wxAUI_MGR_VENETIAN_BLINDS_HINT
) != 0) 
 829             // system can't support transparent fade, or the venetian 
 830             // blinds effect was explicitly requested 
 831             m_hint_wnd 
= new wxPseudoTransparentFrame(m_frame
, 
 836                                                             wxFRAME_TOOL_WINDOW 
| 
 837                                                             wxFRAME_FLOAT_ON_PARENT 
| 
 840             m_hint_fademax 
= 128; 
 846 // SetManagedWindow() is usually called once when the frame 
 847 // manager class is being initialized.  "frame" specifies 
 848 // the frame which should be managed by the frame mananger 
 849 void wxAuiManager::SetManagedWindow(wxWindow
* wnd
) 
 851     wxASSERT_MSG(wnd
, wxT("specified window must be non-NULL")); 
 854     m_frame
->PushEventHandler(this); 
 857     // if the owner is going to manage an MDI parent frame, 
 858     // we need to add the MDI client window as the default 
 861     if (m_frame
->IsKindOf(CLASSINFO(wxMDIParentFrame
))) 
 863         wxMDIParentFrame
* mdi_frame 
= (wxMDIParentFrame
*)m_frame
; 
 864         wxWindow
* client_window 
= mdi_frame
->GetClientWindow(); 
 866         wxASSERT_MSG(client_window
, wxT("Client window is NULL!")); 
 868         AddPane(client_window
, 
 869                 wxAuiPaneInfo().Name(wxT("mdiclient")). 
 870                 CenterPane().PaneBorder(false)); 
 872     else if (m_frame
->IsKindOf(CLASSINFO(wxAuiMDIParentFrame
))) 
 874         wxAuiMDIParentFrame
* mdi_frame 
= (wxAuiMDIParentFrame
*)m_frame
; 
 875         wxAuiMDIClientWindow
* client_window 
= mdi_frame
->GetClientWindow(); 
 876         wxASSERT_MSG(client_window
, wxT("Client window is NULL!")); 
 878         AddPane(client_window
, 
 879                 wxAuiPaneInfo().Name(wxT("mdiclient")). 
 880                 CenterPane().PaneBorder(false)); 
 885     UpdateHintWindowConfig(); 
 889 // UnInit() must be called, usually in the destructor 
 890 // of the frame class.   If it is not called, usually this 
 891 // will result in a crash upon program exit 
 892 void wxAuiManager::UnInit() 
 896         m_frame
->RemoveEventHandler(this); 
 900 // GetManagedWindow() returns the window pointer being managed 
 901 wxWindow
* wxAuiManager::GetManagedWindow() const 
 906 wxAuiDockArt
* wxAuiManager::GetArtProvider() const 
 911 void wxAuiManager::ProcessMgrEvent(wxAuiManagerEvent
& event
) 
 913     // first, give the owner frame a chance to override 
 916         if (m_frame
->ProcessEvent(event
)) 
 923 // SetArtProvider() instructs wxAuiManager to use the 
 924 // specified art provider for all drawing calls.  This allows 
 925 // plugable look-and-feel features.  The pointer that is 
 926 // passed to this method subsequently belongs to wxAuiManager, 
 927 // and is deleted in the frame manager destructor 
 928 void wxAuiManager::SetArtProvider(wxAuiDockArt
* art_provider
) 
 930     // delete the last art provider, if any 
 933     // assign the new art provider 
 934     m_art 
= art_provider
; 
 938 bool wxAuiManager::AddPane(wxWindow
* window
, const wxAuiPaneInfo
& pane_info
) 
 940     // check if the pane has a valid window 
 944     // check if the window is already managed by us 
 945     if (GetPane(pane_info
.window
).IsOk()) 
 948     // check if the pane name already exists, this could reveal a 
 949     // bug in the library user's application 
 950     bool already_exists 
= false; 
 951     if (!pane_info
.name
.empty() && GetPane(pane_info
.name
).IsOk()) 
 953         wxFAIL_MSG(wxT("A pane with that name already exists in the manager!")); 
 954         already_exists 
= true; 
 957     // if the new pane is docked then we should undo maximize 
 958     if (pane_info
.IsDocked()) 
 959         RestoreMaximizedPane(); 
 961     m_panes
.Add(pane_info
); 
 963     wxAuiPaneInfo
& pinfo 
= m_panes
.Last(); 
 965     // set the pane window 
 966     pinfo
.window 
= window
; 
 969     // if the pane's name identifier is blank, create a random string 
 970     if (pinfo
.name
.empty() || already_exists
) 
 972         pinfo
.name
.Printf(wxT("%08lx%08x%08x%08lx"), 
 973              wxPtrToUInt(pinfo
.window
) & 0xffffffff, 
 974              (unsigned int)time(NULL
), 
 976              (unsigned int)GetTickCount(), 
 978              (unsigned int)clock(), 
 980              (unsigned long)m_panes
.GetCount()); 
 983     // set initial proportion (if not already set) 
 984     if (pinfo
.dock_proportion 
== 0) 
 985         pinfo
.dock_proportion 
= 100000; 
 987     if (pinfo
.HasMaximizeButton()) 
 989         wxAuiPaneButton button
; 
 990         button
.button_id 
= wxAUI_BUTTON_MAXIMIZE_RESTORE
; 
 991         pinfo
.buttons
.Add(button
); 
 994     if (pinfo
.HasPinButton()) 
 996         wxAuiPaneButton button
; 
 997         button
.button_id 
= wxAUI_BUTTON_PIN
; 
 998         pinfo
.buttons
.Add(button
); 
1001     if (pinfo
.HasCloseButton()) 
1003         wxAuiPaneButton button
; 
1004         button
.button_id 
= wxAUI_BUTTON_CLOSE
; 
1005         pinfo
.buttons
.Add(button
); 
1008     if (pinfo
.best_size 
== wxDefaultSize 
&& 
1011         pinfo
.best_size 
= pinfo
.window
->GetClientSize(); 
1013         if (pinfo
.window
->IsKindOf(CLASSINFO(wxToolBar
))) 
1015             // GetClientSize() doesn't get the best size for 
1016             // a toolbar under some newer versions of wxWidgets, 
1017             // so use GetBestSize() 
1018             pinfo
.best_size 
= pinfo
.window
->GetBestSize(); 
1020             // for some reason, wxToolBar::GetBestSize() is returning 
1021             // a size that is a pixel shy of the correct amount. 
1022             // I believe this to be the correct action, until 
1023             // wxToolBar::GetBestSize() is fixed.  Is this assumption 
1025             // commented out by JACS 2007-9-08 after having added a pixel in wxMSW's wxToolBar::DoGetBestSize() 
1026             // pinfo.best_size.y++; 
1029         if (pinfo
.min_size 
!= wxDefaultSize
) 
1031             if (pinfo
.best_size
.x 
< pinfo
.min_size
.x
) 
1032                 pinfo
.best_size
.x 
= pinfo
.min_size
.x
; 
1033             if (pinfo
.best_size
.y 
< pinfo
.min_size
.y
) 
1034                 pinfo
.best_size
.y 
= pinfo
.min_size
.y
; 
1041 bool wxAuiManager::AddPane(wxWindow
* window
, 
1043                            const wxString
& caption
) 
1045     wxAuiPaneInfo pinfo
; 
1046     pinfo
.Caption(caption
); 
1049         case wxTOP
:    pinfo
.Top(); break; 
1050         case wxBOTTOM
: pinfo
.Bottom(); break; 
1051         case wxLEFT
:   pinfo
.Left(); break; 
1052         case wxRIGHT
:  pinfo
.Right(); break; 
1053         case wxCENTER
: pinfo
.CenterPane(); break; 
1055     return AddPane(window
, pinfo
); 
1058 bool wxAuiManager::AddPane(wxWindow
* window
, 
1059                            const wxAuiPaneInfo
& pane_info
, 
1060                            const wxPoint
& drop_pos
) 
1062     if (!AddPane(window
, pane_info
)) 
1065     wxAuiPaneInfo
& pane 
= GetPane(window
); 
1067     DoDrop(m_docks
, m_panes
, pane
, drop_pos
, wxPoint(0,0)); 
1072 bool wxAuiManager::InsertPane(wxWindow
* window
, const wxAuiPaneInfo
& pane_info
, 
1075     // shift the panes around, depending on the insert level 
1076     switch (insert_level
) 
1078         case wxAUI_INSERT_PANE
: 
1079             DoInsertPane(m_panes
, 
1080                  pane_info
.dock_direction
, 
1081                  pane_info
.dock_layer
, 
1083                  pane_info
.dock_pos
); 
1085         case wxAUI_INSERT_ROW
: 
1086             DoInsertDockRow(m_panes
, 
1087                  pane_info
.dock_direction
, 
1088                  pane_info
.dock_layer
, 
1089                  pane_info
.dock_row
); 
1091         case wxAUI_INSERT_DOCK
: 
1092             DoInsertDockLayer(m_panes
, 
1093                  pane_info
.dock_direction
, 
1094                  pane_info
.dock_layer
); 
1098     // if the window already exists, we are basically just moving/inserting the 
1099     // existing window.  If it doesn't exist, we need to add it and insert it 
1100     wxAuiPaneInfo
& existing_pane 
= GetPane(window
); 
1101     if (!existing_pane
.IsOk()) 
1103         return AddPane(window
, pane_info
); 
1107         if (pane_info
.IsFloating()) 
1109             existing_pane
.Float(); 
1110             if (pane_info
.floating_pos 
!= wxDefaultPosition
) 
1111                 existing_pane
.FloatingPosition(pane_info
.floating_pos
); 
1112             if (pane_info
.floating_size 
!= wxDefaultSize
) 
1113                 existing_pane
.FloatingSize(pane_info
.floating_size
); 
1117             // if the new pane is docked then we should undo maximize 
1118             RestoreMaximizedPane(); 
1120             existing_pane
.Direction(pane_info
.dock_direction
); 
1121             existing_pane
.Layer(pane_info
.dock_layer
); 
1122             existing_pane
.Row(pane_info
.dock_row
); 
1123             existing_pane
.Position(pane_info
.dock_pos
); 
1131 // DetachPane() removes a pane from the frame manager.  This 
1132 // method will not destroy the window that is removed. 
1133 bool wxAuiManager::DetachPane(wxWindow
* window
) 
1136     for (i 
= 0, count 
= m_panes
.GetCount(); i 
< count
; ++i
) 
1138         wxAuiPaneInfo
& p 
= m_panes
.Item(i
); 
1139         if (p
.window 
== window
) 
1143                 // we have a floating frame which is being detached. We need to 
1144                 // reparent it to m_frame and destroy the floating frame 
1147                 p
.window
->SetSize(1,1); 
1149                 if (p
.frame
->IsShown()) 
1150                     p
.frame
->Show(false); 
1152                 // reparent to m_frame and destroy the pane 
1153                 if (m_action_window 
== p
.frame
) 
1155                     m_action_window 
= NULL
; 
1158                 p
.window
->Reparent(m_frame
); 
1159                 p
.frame
->SetSizer(NULL
); 
1164             // make sure there are no references to this pane in our uiparts, 
1165             // just in case the caller doesn't call Update() immediately after 
1166             // the DetachPane() call.  This prevets obscure crashes which would 
1167             // happen at window repaint if the caller forgets to call Update() 
1169             for (pi 
= 0, part_count 
= (int)m_uiparts
.GetCount(); pi 
< part_count
; ++pi
) 
1171                 wxAuiDockUIPart
& part 
= m_uiparts
.Item(pi
); 
1172                 if (part
.pane 
== &p
) 
1174                     m_uiparts
.RemoveAt(pi
); 
1181             m_panes
.RemoveAt(i
); 
1188 // ClosePane() destroys or hides the pane depending on its flags 
1189 void wxAuiManager::ClosePane(wxAuiPaneInfo
& pane_info
) 
1191     // if we were maximized, restore 
1192     if (pane_info
.IsMaximized()) 
1194         RestorePane(pane_info
); 
1197     // first, hide the window 
1198     if (pane_info
.window 
&& pane_info
.window
->IsShown()) 
1200         pane_info
.window
->Show(false); 
1203     // make sure that we are the parent of this window 
1204     if (pane_info
.window 
&& pane_info
.window
->GetParent() != m_frame
) 
1206         pane_info
.window
->Reparent(m_frame
); 
1209     // if we have a frame, destroy it 
1210     if (pane_info
.frame
) 
1212         pane_info
.frame
->Destroy(); 
1213         pane_info
.frame 
= NULL
; 
1216     // now we need to either destroy or hide the pane 
1217     if (pane_info
.IsDestroyOnClose()) 
1219         wxWindow 
* window 
= pane_info
.window
; 
1232 void wxAuiManager::MaximizePane(wxAuiPaneInfo
& pane_info
) 
1236     // un-maximize and hide all other panes 
1237     for (i 
= 0, pane_count 
= m_panes
.GetCount(); i 
< pane_count
; ++i
) 
1239         wxAuiPaneInfo
& p 
= m_panes
.Item(i
); 
1244             // save hidden state 
1245             p
.SetFlag(wxAuiPaneInfo::savedHiddenState
, 
1246                       p
.HasFlag(wxAuiPaneInfo::optionHidden
)); 
1248             // hide the pane, because only the newly 
1249             // maximized pane should show 
1254     // mark ourselves maximized 
1255     pane_info
.Maximize(); 
1257     m_has_maximized 
= true; 
1259     // last, show the window 
1260     if (pane_info
.window 
&& !pane_info
.window
->IsShown()) 
1262         pane_info
.window
->Show(true); 
1266 void wxAuiManager::RestorePane(wxAuiPaneInfo
& pane_info
) 
1270     // restore all the panes 
1271     for (i 
= 0, pane_count 
= m_panes
.GetCount(); i 
< pane_count
; ++i
) 
1273         wxAuiPaneInfo
& p 
= m_panes
.Item(i
); 
1276             p
.SetFlag(wxAuiPaneInfo::optionHidden
, 
1277                       p
.HasFlag(wxAuiPaneInfo::savedHiddenState
)); 
1281     // mark ourselves non-maximized 
1282     pane_info
.Restore(); 
1283     m_has_maximized 
= false; 
1285     // last, show the window 
1286     if (pane_info
.window 
&& !pane_info
.window
->IsShown()) 
1288         pane_info
.window
->Show(true); 
1292 void wxAuiManager::RestoreMaximizedPane() 
1296     // restore all the panes 
1297     for (i 
= 0, pane_count 
= m_panes
.GetCount(); i 
< pane_count
; ++i
) 
1299         wxAuiPaneInfo
& p 
= m_panes
.Item(i
); 
1300         if (p
.IsMaximized()) 
1308 // EscapeDelimiters() changes ";" into "\;" and "|" into "\|" 
1309 // in the input string.  This is an internal functions which is 
1310 // used for saving perspectives 
1311 static wxString 
EscapeDelimiters(const wxString
& s
) 
1314     result
.Alloc(s
.length()); 
1315     const wxChar
* ch 
= s
.c_str(); 
1318         if (*ch 
== wxT(';') || *ch 
== wxT('|')) 
1319             result 
+= wxT('\\'); 
1326 wxString 
wxAuiManager::SavePaneInfo(wxAuiPaneInfo
& pane
) 
1328     wxString result 
= wxT("name="); 
1329     result 
+= EscapeDelimiters(pane
.name
); 
1332     result 
+= wxT("caption="); 
1333     result 
+= EscapeDelimiters(pane
.caption
); 
1336     result 
+= wxString::Format(wxT("state=%u;"), pane
.state
); 
1337     result 
+= wxString::Format(wxT("dir=%d;"), pane
.dock_direction
); 
1338     result 
+= wxString::Format(wxT("layer=%d;"), pane
.dock_layer
); 
1339     result 
+= wxString::Format(wxT("row=%d;"), pane
.dock_row
); 
1340     result 
+= wxString::Format(wxT("pos=%d;"), pane
.dock_pos
); 
1341     result 
+= wxString::Format(wxT("prop=%d;"), pane
.dock_proportion
); 
1342     result 
+= wxString::Format(wxT("bestw=%d;"), pane
.best_size
.x
); 
1343     result 
+= wxString::Format(wxT("besth=%d;"), pane
.best_size
.y
); 
1344     result 
+= wxString::Format(wxT("minw=%d;"), pane
.min_size
.x
); 
1345     result 
+= wxString::Format(wxT("minh=%d;"), pane
.min_size
.y
); 
1346     result 
+= wxString::Format(wxT("maxw=%d;"), pane
.max_size
.x
); 
1347     result 
+= wxString::Format(wxT("maxh=%d;"), pane
.max_size
.y
); 
1348     result 
+= wxString::Format(wxT("floatx=%d;"), pane
.floating_pos
.x
); 
1349     result 
+= wxString::Format(wxT("floaty=%d;"), pane
.floating_pos
.y
); 
1350     result 
+= wxString::Format(wxT("floatw=%d;"), pane
.floating_size
.x
); 
1351     result 
+= wxString::Format(wxT("floath=%d"), pane
.floating_size
.y
); 
1356 // Load a "pane" with the pane infor settings in pane_part 
1357 void wxAuiManager::LoadPaneInfo(wxString pane_part
, wxAuiPaneInfo 
&pane
) 
1359     // replace escaped characters so we can 
1360     // split up the string easily 
1361     pane_part
.Replace(wxT("\\|"), wxT("\a")); 
1362     pane_part
.Replace(wxT("\\;"), wxT("\b")); 
1366         wxString val_part 
= pane_part
.BeforeFirst(wxT(';')); 
1367         pane_part 
= pane_part
.AfterFirst(wxT(';')); 
1368         wxString val_name 
= val_part
.BeforeFirst(wxT('=')); 
1369         wxString value 
= val_part
.AfterFirst(wxT('=')); 
1370         val_name
.MakeLower(); 
1371         val_name
.Trim(true); 
1372         val_name
.Trim(false); 
1376         if (val_name
.empty()) 
1379         if (val_name 
== wxT("name")) 
1381         else if (val_name 
== wxT("caption")) 
1382             pane
.caption 
= value
; 
1383         else if (val_name 
== wxT("state")) 
1384             pane
.state 
= (unsigned int)wxAtoi(value
.c_str()); 
1385         else if (val_name 
== wxT("dir")) 
1386             pane
.dock_direction 
= wxAtoi(value
.c_str()); 
1387         else if (val_name 
== wxT("layer")) 
1388             pane
.dock_layer 
= wxAtoi(value
.c_str()); 
1389         else if (val_name 
== wxT("row")) 
1390             pane
.dock_row 
= wxAtoi(value
.c_str()); 
1391         else if (val_name 
== wxT("pos")) 
1392             pane
.dock_pos 
= wxAtoi(value
.c_str()); 
1393         else if (val_name 
== wxT("prop")) 
1394             pane
.dock_proportion 
= wxAtoi(value
.c_str()); 
1395         else if (val_name 
== wxT("bestw")) 
1396             pane
.best_size
.x 
= wxAtoi(value
.c_str()); 
1397         else if (val_name 
== wxT("besth")) 
1398             pane
.best_size
.y 
= wxAtoi(value
.c_str()); 
1399         else if (val_name 
== wxT("minw")) 
1400             pane
.min_size
.x 
= wxAtoi(value
.c_str()); 
1401         else if (val_name 
== wxT("minh")) 
1402             pane
.min_size
.y 
= wxAtoi(value
.c_str()); 
1403         else if (val_name 
== wxT("maxw")) 
1404             pane
.max_size
.x 
= wxAtoi(value
.c_str()); 
1405         else if (val_name 
== wxT("maxh")) 
1406             pane
.max_size
.y 
= wxAtoi(value
.c_str()); 
1407         else if (val_name 
== wxT("floatx")) 
1408             pane
.floating_pos
.x 
= wxAtoi(value
.c_str()); 
1409         else if (val_name 
== wxT("floaty")) 
1410             pane
.floating_pos
.y 
= wxAtoi(value
.c_str()); 
1411         else if (val_name 
== wxT("floatw")) 
1412             pane
.floating_size
.x 
= wxAtoi(value
.c_str()); 
1413         else if (val_name 
== wxT("floath")) 
1414             pane
.floating_size
.y 
= wxAtoi(value
.c_str()); 
1416             wxFAIL_MSG(wxT("Bad Perspective String")); 
1420     // replace escaped characters so we can 
1421     // split up the string easily 
1422     pane
.name
.Replace(wxT("\a"), wxT("|")); 
1423     pane
.name
.Replace(wxT("\b"), wxT(";")); 
1424     pane
.caption
.Replace(wxT("\a"), wxT("|")); 
1425     pane
.caption
.Replace(wxT("\b"), wxT(";")); 
1426     pane_part
.Replace(wxT("\a"), wxT("|")); 
1427     pane_part
.Replace(wxT("\b"), wxT(";")); 
1433 // SavePerspective() saves all pane information as a single string. 
1434 // This string may later be fed into LoadPerspective() to restore 
1435 // all pane settings.  This save and load mechanism allows an 
1436 // exact pane configuration to be saved and restored at a later time 
1438 wxString 
wxAuiManager::SavePerspective() 
1442     result 
= wxT("layout2|"); 
1444     int pane_i
, pane_count 
= m_panes
.GetCount(); 
1445     for (pane_i 
= 0; pane_i 
< pane_count
; ++pane_i
) 
1447         wxAuiPaneInfo
& pane 
= m_panes
.Item(pane_i
); 
1448         result 
+= SavePaneInfo(pane
)+wxT("|"); 
1451     int dock_i
, dock_count 
= m_docks
.GetCount(); 
1452     for (dock_i 
= 0; dock_i 
< dock_count
; ++dock_i
) 
1454         wxAuiDockInfo
& dock 
= m_docks
.Item(dock_i
); 
1456         result 
+= wxString::Format(wxT("dock_size(%d,%d,%d)=%d|"), 
1457                                    dock
.dock_direction
, dock
.dock_layer
, 
1458                                    dock
.dock_row
, dock
.size
); 
1464 // LoadPerspective() loads a layout which was saved with SavePerspective() 
1465 // If the "update" flag parameter is true, the GUI will immediately be updated 
1467 bool wxAuiManager::LoadPerspective(const wxString
& layout
, bool update
) 
1469     wxString input 
= layout
; 
1472     // check layout string version 
1473     //    'layout1' = wxAUI 0.9.0 - wxAUI 0.9.2 
1474     //    'layout2' = wxAUI 0.9.2 (wxWidgets 2.8) 
1475     part 
= input
.BeforeFirst(wxT('|')); 
1476     input 
= input
.AfterFirst(wxT('|')); 
1479     if (part 
!= wxT("layout2")) 
1482     // mark all panes currently managed as docked and hidden 
1483     int pane_i
, pane_count 
= m_panes
.GetCount(); 
1484     for (pane_i 
= 0; pane_i 
< pane_count
; ++pane_i
) 
1485         m_panes
.Item(pane_i
).Dock().Hide(); 
1487     // clear out the dock array; this will be reconstructed 
1490     // replace escaped characters so we can 
1491     // split up the string easily 
1492     input
.Replace(wxT("\\|"), wxT("\a")); 
1493     input
.Replace(wxT("\\;"), wxT("\b")); 
1499         wxString pane_part 
= input
.BeforeFirst(wxT('|')); 
1500         input 
= input
.AfterFirst(wxT('|')); 
1501         pane_part
.Trim(true); 
1503         // if the string is empty, we're done parsing 
1504         if (pane_part
.empty()) 
1507         if (pane_part
.Left(9) == wxT("dock_size")) 
1509             wxString val_name 
= pane_part
.BeforeFirst(wxT('=')); 
1510             wxString value 
= pane_part
.AfterFirst(wxT('=')); 
1512             long dir
, layer
, row
, size
; 
1513             wxString piece 
= val_name
.AfterFirst(wxT('(')); 
1514             piece 
= piece
.BeforeLast(wxT(')')); 
1515             piece
.BeforeFirst(wxT(',')).ToLong(&dir
); 
1516             piece 
= piece
.AfterFirst(wxT(',')); 
1517             piece
.BeforeFirst(wxT(',')).ToLong(&layer
); 
1518             piece
.AfterFirst(wxT(',')).ToLong(&row
); 
1519             value
.ToLong(&size
); 
1522             dock
.dock_direction 
= dir
; 
1523             dock
.dock_layer 
= layer
; 
1524             dock
.dock_row 
= row
; 
1530         // Undo our escaping as LoadPaneInfo needs to take an unescaped 
1531         // name so it can be called by external callers 
1532         pane_part
.Replace(wxT("\a"), wxT("|")); 
1533         pane_part
.Replace(wxT("\b"), wxT(";")); 
1535         LoadPaneInfo(pane_part
, pane
); 
1537         wxAuiPaneInfo
& p 
= GetPane(pane
.name
); 
1540             // the pane window couldn't be found 
1541             // in the existing layout -- skip it 
1554 void wxAuiManager::GetPanePositionsAndSizes(wxAuiDockInfo
& dock
, 
1555                                             wxArrayInt
& positions
, 
1558     int caption_size 
= m_art
->GetMetric(wxAUI_DOCKART_CAPTION_SIZE
); 
1559     int pane_border_size 
= m_art
->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE
); 
1560     int gripper_size 
= m_art
->GetMetric(wxAUI_DOCKART_GRIPPER_SIZE
); 
1565     int offset
, action_pane 
= -1; 
1566     int pane_i
, pane_count 
= dock
.panes
.GetCount(); 
1568     // find the pane marked as our action pane 
1569     for (pane_i 
= 0; pane_i 
< pane_count
; ++pane_i
) 
1571         wxAuiPaneInfo
& pane 
= *(dock
.panes
.Item(pane_i
)); 
1573         if (pane
.state 
& wxAuiPaneInfo::actionPane
) 
1575             wxASSERT_MSG(action_pane
==-1, wxT("Too many fixed action panes")); 
1576             action_pane 
= pane_i
; 
1580     // set up each panes default position, and 
1581     // determine the size (width or height, depending 
1582     // on the dock's orientation) of each pane 
1583     for (pane_i 
= 0; pane_i 
< pane_count
; ++pane_i
) 
1585         wxAuiPaneInfo
& pane 
= *(dock
.panes
.Item(pane_i
)); 
1586         positions
.Add(pane
.dock_pos
); 
1589         if (pane
.HasBorder()) 
1590             size 
+= (pane_border_size
*2); 
1592         if (dock
.IsHorizontal()) 
1594             if (pane
.HasGripper() && !pane
.HasGripperTop()) 
1595                 size 
+= gripper_size
; 
1596             size 
+= pane
.best_size
.x
; 
1600             if (pane
.HasGripper() && pane
.HasGripperTop()) 
1601                 size 
+= gripper_size
; 
1603             if (pane
.HasCaption()) 
1604                 size 
+= caption_size
; 
1605             size 
+= pane
.best_size
.y
; 
1611     // if there is no action pane, just return the default 
1612     // positions (as specified in pane.pane_pos) 
1613     if (action_pane 
== -1) 
1617     for (pane_i 
= action_pane
-1; pane_i 
>= 0; --pane_i
) 
1619         int amount 
= positions
[pane_i
+1] - (positions
[pane_i
] + sizes
[pane_i
]); 
1624             positions
[pane_i
] -= -amount
; 
1626         offset 
+= sizes
[pane_i
]; 
1629     // if the dock mode is fixed, make sure none of the panes 
1630     // overlap; we will bump panes that overlap 
1632     for (pane_i 
= action_pane
; pane_i 
< pane_count
; ++pane_i
) 
1634         int amount 
= positions
[pane_i
] - offset
; 
1638             positions
[pane_i
] += -amount
; 
1640         offset 
+= sizes
[pane_i
]; 
1645 void wxAuiManager::LayoutAddPane(wxSizer
* cont
, 
1646                                  wxAuiDockInfo
& dock
, 
1647                                  wxAuiPaneInfo
& pane
, 
1648                                  wxAuiDockUIPartArray
& uiparts
, 
1651     wxAuiDockUIPart part
; 
1652     wxSizerItem
* sizer_item
; 
1654     int caption_size 
= m_art
->GetMetric(wxAUI_DOCKART_CAPTION_SIZE
); 
1655     int gripper_size 
= m_art
->GetMetric(wxAUI_DOCKART_GRIPPER_SIZE
); 
1656     int pane_border_size 
= m_art
->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE
); 
1657     int pane_button_size 
= m_art
->GetMetric(wxAUI_DOCKART_PANE_BUTTON_SIZE
); 
1659     // find out the orientation of the item (orientation for panes 
1660     // is the same as the dock's orientation) 
1662     if (dock
.IsHorizontal()) 
1663         orientation 
= wxHORIZONTAL
; 
1665         orientation 
= wxVERTICAL
; 
1667     // this variable will store the proportion 
1668     // value that the pane will receive 
1669     int pane_proportion 
= pane
.dock_proportion
; 
1671     wxBoxSizer
* horz_pane_sizer 
= new wxBoxSizer(wxHORIZONTAL
); 
1672     wxBoxSizer
* vert_pane_sizer 
= new wxBoxSizer(wxVERTICAL
); 
1674     if (pane
.HasGripper()) 
1676         if (pane
.HasGripperTop()) 
1677             sizer_item 
= vert_pane_sizer 
->Add(1, gripper_size
, 0, wxEXPAND
); 
1679             sizer_item 
= horz_pane_sizer 
->Add(gripper_size
, 1, 0, wxEXPAND
); 
1681         part
.type 
= wxAuiDockUIPart::typeGripper
; 
1685         part
.orientation 
= orientation
; 
1686         part
.cont_sizer 
= horz_pane_sizer
; 
1687         part
.sizer_item 
= sizer_item
; 
1691     if (pane
.HasCaption()) 
1693         // create the caption sizer 
1694         wxBoxSizer
* caption_sizer 
= new wxBoxSizer(wxHORIZONTAL
); 
1696         sizer_item 
= caption_sizer
->Add(1, caption_size
, 1, wxEXPAND
); 
1698         part
.type 
= wxAuiDockUIPart::typeCaption
; 
1702         part
.orientation 
= orientation
; 
1703         part
.cont_sizer 
= vert_pane_sizer
; 
1704         part
.sizer_item 
= sizer_item
; 
1705         int caption_part_idx 
= uiparts
.GetCount(); 
1708         // add pane buttons to the caption 
1709         int i
, button_count
; 
1710         for (i 
= 0, button_count 
= pane
.buttons
.GetCount(); 
1711              i 
< button_count
; ++i
) 
1713             wxAuiPaneButton
& button 
= pane
.buttons
.Item(i
); 
1715             sizer_item 
= caption_sizer
->Add(pane_button_size
, 
1719             part
.type 
= wxAuiDockUIPart::typePaneButton
; 
1722             part
.button 
= &button
; 
1723             part
.orientation 
= orientation
; 
1724             part
.cont_sizer 
= caption_sizer
; 
1725             part
.sizer_item 
= sizer_item
; 
1729         // if we have buttons, add a little space to the right 
1730         // of them to ease visual crowding 
1731         if (button_count 
>= 1) 
1733             caption_sizer
->Add(3,1); 
1736         // add the caption sizer 
1737         sizer_item 
= vert_pane_sizer
->Add(caption_sizer
, 0, wxEXPAND
); 
1739         uiparts
.Item(caption_part_idx
).sizer_item 
= sizer_item
; 
1742     // add the pane window itself 
1745         sizer_item 
= vert_pane_sizer
->Add(1, 1, 1, wxEXPAND
); 
1749         sizer_item 
= vert_pane_sizer
->Add(pane
.window
, 1, wxEXPAND
); 
1750         // Don't do this because it breaks the pane size in floating windows 
1751         // BIW: Right now commenting this out is causing problems with 
1752         // an mdi client window as the center pane. 
1753         vert_pane_sizer
->SetItemMinSize(pane
.window
, 1, 1); 
1756     part
.type 
= wxAuiDockUIPart::typePane
; 
1760     part
.orientation 
= orientation
; 
1761     part
.cont_sizer 
= vert_pane_sizer
; 
1762     part
.sizer_item 
= sizer_item
; 
1766     // determine if the pane should have a minimum size; if the pane is 
1767     // non-resizable (fixed) then we must set a minimum size. Alternatively, 
1768     // if the pane.min_size is set, we must use that value as well 
1770     wxSize min_size 
= pane
.min_size
; 
1773         if (min_size 
== wxDefaultSize
) 
1775             min_size 
= pane
.best_size
; 
1776             pane_proportion 
= 0; 
1780     if (min_size 
!= wxDefaultSize
) 
1782         vert_pane_sizer
->SetItemMinSize( 
1783                         vert_pane_sizer
->GetChildren().GetCount()-1, 
1784                         min_size
.x
, min_size
.y
); 
1788     // add the verticle sizer (caption, pane window) to the 
1789     // horizontal sizer (gripper, verticle sizer) 
1790     horz_pane_sizer
->Add(vert_pane_sizer
, 1, wxEXPAND
); 
1792     // finally, add the pane sizer to the dock sizer 
1794     if (pane
.HasBorder()) 
1796         // allowing space for the pane's border 
1797         sizer_item 
= cont
->Add(horz_pane_sizer
, pane_proportion
, 
1798                                wxEXPAND 
| wxALL
, pane_border_size
); 
1800         part
.type 
= wxAuiDockUIPart::typePaneBorder
; 
1804         part
.orientation 
= orientation
; 
1805         part
.cont_sizer 
= cont
; 
1806         part
.sizer_item 
= sizer_item
; 
1811         sizer_item 
= cont
->Add(horz_pane_sizer
, pane_proportion
, wxEXPAND
); 
1815 void wxAuiManager::LayoutAddDock(wxSizer
* cont
, 
1816                                  wxAuiDockInfo
& dock
, 
1817                                  wxAuiDockUIPartArray
& uiparts
, 
1820     wxSizerItem
* sizer_item
; 
1821     wxAuiDockUIPart part
; 
1823     int sash_size 
= m_art
->GetMetric(wxAUI_DOCKART_SASH_SIZE
); 
1824     int orientation 
= dock
.IsHorizontal() ? wxHORIZONTAL 
: wxVERTICAL
; 
1826     // resizable bottom and right docks have a sash before them 
1827     if (!m_has_maximized 
&& !dock
.fixed 
&& (dock
.dock_direction 
== wxAUI_DOCK_BOTTOM 
|| 
1828                         dock
.dock_direction 
== wxAUI_DOCK_RIGHT
)) 
1830         sizer_item 
= cont
->Add(sash_size
, sash_size
, 0, wxEXPAND
); 
1832         part
.type 
= wxAuiDockUIPart::typeDockSizer
; 
1833         part
.orientation 
= orientation
; 
1837         part
.cont_sizer 
= cont
; 
1838         part
.sizer_item 
= sizer_item
; 
1842     // create the sizer for the dock 
1843     wxSizer
* dock_sizer 
= new wxBoxSizer(orientation
); 
1845     // add each pane to the dock 
1846     bool has_maximized_pane 
= false; 
1847     int pane_i
, pane_count 
= dock
.panes
.GetCount(); 
1851         wxArrayInt pane_positions
, pane_sizes
; 
1853         // figure out the real pane positions we will 
1854         // use, without modifying the each pane's pane_pos member 
1855         GetPanePositionsAndSizes(dock
, pane_positions
, pane_sizes
); 
1858         for (pane_i 
= 0; pane_i 
< pane_count
; ++pane_i
) 
1860             wxAuiPaneInfo
& pane 
= *(dock
.panes
.Item(pane_i
)); 
1861             int pane_pos 
= pane_positions
.Item(pane_i
); 
1863             if (pane
.IsMaximized()) 
1864                 has_maximized_pane 
= true; 
1867             int amount 
= pane_pos 
- offset
; 
1870                 if (dock
.IsVertical()) 
1871                     sizer_item 
= dock_sizer
->Add(1, amount
, 0, wxEXPAND
); 
1873                     sizer_item 
= dock_sizer
->Add(amount
, 1, 0, wxEXPAND
); 
1875                 part
.type 
= wxAuiDockUIPart::typeBackground
; 
1879                 part
.orientation 
= (orientation
==wxHORIZONTAL
) ? wxVERTICAL
:wxHORIZONTAL
; 
1880                 part
.cont_sizer 
= dock_sizer
; 
1881                 part
.sizer_item 
= sizer_item
; 
1887             LayoutAddPane(dock_sizer
, dock
, pane
, uiparts
, spacer_only
); 
1889             offset 
+= pane_sizes
.Item(pane_i
); 
1892         // at the end add a very small stretchable background area 
1893         sizer_item 
= dock_sizer
->Add(0,0, 1, wxEXPAND
); 
1895         part
.type 
= wxAuiDockUIPart::typeBackground
; 
1899         part
.orientation 
= orientation
; 
1900         part
.cont_sizer 
= dock_sizer
; 
1901         part
.sizer_item 
= sizer_item
; 
1906         for (pane_i 
= 0; pane_i 
< pane_count
; ++pane_i
) 
1908             wxAuiPaneInfo
& pane 
= *(dock
.panes
.Item(pane_i
)); 
1910             if (pane
.IsMaximized()) 
1911                 has_maximized_pane 
= true; 
1913             // if this is not the first pane being added, 
1914             // we need to add a pane sizer 
1915             if (!m_has_maximized 
&& pane_i 
> 0) 
1917                 sizer_item 
= dock_sizer
->Add(sash_size
, sash_size
, 0, wxEXPAND
); 
1919                 part
.type 
= wxAuiDockUIPart::typePaneSizer
; 
1921                 part
.pane 
= dock
.panes
.Item(pane_i
-1); 
1923                 part
.orientation 
= (orientation
==wxHORIZONTAL
) ? wxVERTICAL
:wxHORIZONTAL
; 
1924                 part
.cont_sizer 
= dock_sizer
; 
1925                 part
.sizer_item 
= sizer_item
; 
1929             LayoutAddPane(dock_sizer
, dock
, pane
, uiparts
, spacer_only
); 
1933     if (dock
.dock_direction 
== wxAUI_DOCK_CENTER 
|| has_maximized_pane
) 
1934         sizer_item 
= cont
->Add(dock_sizer
, 1, wxEXPAND
); 
1936         sizer_item 
= cont
->Add(dock_sizer
, 0, wxEXPAND
); 
1938     part
.type 
= wxAuiDockUIPart::typeDock
; 
1942     part
.orientation 
= orientation
; 
1943     part
.cont_sizer 
= cont
; 
1944     part
.sizer_item 
= sizer_item
; 
1947     if (dock
.IsHorizontal()) 
1948         cont
->SetItemMinSize(dock_sizer
, 0, dock
.size
); 
1950         cont
->SetItemMinSize(dock_sizer
, dock
.size
, 0); 
1952     //  top and left docks have a sash after them 
1953     if (!m_has_maximized 
&& 
1955           (dock
.dock_direction 
== wxAUI_DOCK_TOP 
|| 
1956            dock
.dock_direction 
== wxAUI_DOCK_LEFT
)) 
1958         sizer_item 
= cont
->Add(sash_size
, sash_size
, 0, wxEXPAND
); 
1960         part
.type 
= wxAuiDockUIPart::typeDockSizer
; 
1964         part
.orientation 
= orientation
; 
1965         part
.cont_sizer 
= cont
; 
1966         part
.sizer_item 
= sizer_item
; 
1971 wxSizer
* wxAuiManager::LayoutAll(wxAuiPaneInfoArray
& panes
, 
1972                                  wxAuiDockInfoArray
& docks
, 
1973                                  wxAuiDockUIPartArray
& uiparts
, 
1976     wxBoxSizer
* container 
= new wxBoxSizer(wxVERTICAL
); 
1978     int pane_border_size 
= m_art
->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE
); 
1979     int caption_size 
= m_art
->GetMetric(wxAUI_DOCKART_CAPTION_SIZE
); 
1980     wxSize cli_size 
= m_frame
->GetClientSize(); 
1981     int i
, dock_count
, pane_count
; 
1984     // empty all docks out 
1985     for (i 
= 0, dock_count 
= docks
.GetCount(); i 
< dock_count
; ++i
) 
1987         wxAuiDockInfo
& dock 
= docks
.Item(i
); 
1989         // empty out all panes, as they will be readded below 
1994             // always reset fixed docks' sizes, because 
1995             // the contained windows may have been resized 
2001     // iterate through all known panes, filing each 
2002     // of them into the appropriate dock. If the 
2003     // pane does not exist in the dock, add it 
2004     for (i 
= 0, pane_count 
= panes
.GetCount(); i 
< pane_count
; ++i
) 
2006         wxAuiPaneInfo
& p 
= panes
.Item(i
); 
2008         // find any docks with the same dock direction, dock layer, and 
2009         // dock row as the pane we are working on 
2010         wxAuiDockInfo
* dock
; 
2011         wxAuiDockInfoPtrArray arr
; 
2012         FindDocks(docks
, p
.dock_direction
, p
.dock_layer
, p
.dock_row
, arr
); 
2014         if (arr
.GetCount() > 0) 
2016             // found the right dock 
2021             // dock was not found, so we need to create a new one 
2023             d
.dock_direction 
= p
.dock_direction
; 
2024             d
.dock_layer 
= p
.dock_layer
; 
2025             d
.dock_row 
= p
.dock_row
; 
2027             dock 
= &docks
.Last(); 
2031         if (p
.IsDocked() && p
.IsShown()) 
2033             // remove the pane from any existing docks except this one 
2034             RemovePaneFromDocks(docks
, p
, dock
); 
2036             // pane needs to be added to the dock, 
2037             // if it doesn't already exist 
2038             if (!FindPaneInDock(*dock
, p
.window
)) 
2039                 dock
->panes
.Add(&p
); 
2043             // remove the pane from any existing docks 
2044             RemovePaneFromDocks(docks
, p
); 
2049     // remove any empty docks 
2050     for (i 
= docks
.GetCount()-1; i 
>= 0; --i
) 
2052         if (docks
.Item(i
).panes
.GetCount() == 0) 
2056     // configure the docks further 
2057     for (i 
= 0, dock_count 
= docks
.GetCount(); i 
< dock_count
; ++i
) 
2059         wxAuiDockInfo
& dock 
= docks
.Item(i
); 
2060         int j
, dock_pane_count 
= dock
.panes
.GetCount(); 
2062         // sort the dock pane array by the pane's 
2063         // dock position (dock_pos), in ascending order 
2064         dock
.panes
.Sort(PaneSortFunc
); 
2066         // for newly created docks, set up their initial size 
2071             for (j 
= 0; j 
< dock_pane_count
; ++j
) 
2073                 wxAuiPaneInfo
& pane 
= *dock
.panes
.Item(j
); 
2074                 wxSize pane_size 
= pane
.best_size
; 
2075                 if (pane_size 
== wxDefaultSize
) 
2076                     pane_size 
= pane
.min_size
; 
2077                 if (pane_size 
== wxDefaultSize
) 
2078                     pane_size 
= pane
.window
->GetSize(); 
2080                 if (dock
.IsHorizontal()) 
2081                     size 
= wxMax(pane_size
.y
, size
); 
2083                     size 
= wxMax(pane_size
.x
, size
); 
2086             // add space for the border (two times), but only 
2087             // if at least one pane inside the dock has a pane border 
2088             for (j 
= 0; j 
< dock_pane_count
; ++j
) 
2090                 if (dock
.panes
.Item(j
)->HasBorder()) 
2092                     size 
+= (pane_border_size
*2); 
2097             // if pane is on the top or bottom, add the caption height, 
2098             // but only if at least one pane inside the dock has a caption 
2099             if (dock
.IsHorizontal()) 
2101                 for (j 
= 0; j 
< dock_pane_count
; ++j
) 
2103                     if (dock
.panes
.Item(j
)->HasCaption()) 
2105                         size 
+= caption_size
; 
2112             // new dock's size may not be more than the dock constraint 
2113             // parameter specifies.  See SetDockSizeConstraint() 
2115             int max_dock_x_size 
= (int)(m_dock_constraint_x 
* ((double)cli_size
.x
)); 
2116             int max_dock_y_size 
= (int)(m_dock_constraint_y 
* ((double)cli_size
.y
)); 
2118             if (dock
.IsHorizontal()) 
2119                 size 
= wxMin(size
, max_dock_y_size
); 
2121                 size 
= wxMin(size
, max_dock_x_size
); 
2123             // absolute minimum size for a dock is 10 pixels 
2131         // determine the dock's minimum size 
2132         bool plus_border 
= false; 
2133         bool plus_caption 
= false; 
2134         int dock_min_size 
= 0; 
2135         for (j 
= 0; j 
< dock_pane_count
; ++j
) 
2137             wxAuiPaneInfo
& pane 
= *dock
.panes
.Item(j
); 
2138             if (pane
.min_size 
!= wxDefaultSize
) 
2140                 if (pane
.HasBorder()) 
2142                 if (pane
.HasCaption()) 
2143                     plus_caption 
= true; 
2144                 if (dock
.IsHorizontal()) 
2146                     if (pane
.min_size
.y 
> dock_min_size
) 
2147                         dock_min_size 
= pane
.min_size
.y
; 
2151                     if (pane
.min_size
.x 
> dock_min_size
) 
2152                         dock_min_size 
= pane
.min_size
.x
; 
2158             dock_min_size 
+= (pane_border_size
*2); 
2159         if (plus_caption 
&& dock
.IsHorizontal()) 
2160             dock_min_size 
+= (caption_size
); 
2162         dock
.min_size 
= dock_min_size
; 
2165         // if the pane's current size is less than it's 
2166         // minimum, increase the dock's size to it's minimum 
2167         if (dock
.size 
< dock
.min_size
) 
2168             dock
.size 
= dock
.min_size
; 
2171         // determine the dock's mode (fixed or proportional); 
2172         // determine whether the dock has only toolbars 
2173         bool action_pane_marked 
= false; 
2175         dock
.toolbar 
= true; 
2176         for (j 
= 0; j 
< dock_pane_count
; ++j
) 
2178             wxAuiPaneInfo
& pane 
= *dock
.panes
.Item(j
); 
2179             if (!pane
.IsFixed()) 
2181             if (!pane
.IsToolbar()) 
2182                 dock
.toolbar 
= false; 
2183             if (pane
.HasFlag(wxAuiPaneInfo::optionDockFixed
)) 
2185             if (pane
.state 
& wxAuiPaneInfo::actionPane
) 
2186                 action_pane_marked 
= true; 
2190         // if the dock mode is proportional and not fixed-pixel, 
2191         // reassign the dock_pos to the sequential 0, 1, 2, 3; 
2192         // e.g. remove gaps like 1, 2, 30, 500 
2195             for (j 
= 0; j 
< dock_pane_count
; ++j
) 
2197                 wxAuiPaneInfo
& pane 
= *dock
.panes
.Item(j
); 
2202         // if the dock mode is fixed, and none of the panes 
2203         // are being moved right now, make sure the panes 
2204         // do not overlap each other.  If they do, we will 
2205         // adjust the positions of the panes 
2206         if (dock
.fixed 
&& !action_pane_marked
) 
2208             wxArrayInt pane_positions
, pane_sizes
; 
2209             GetPanePositionsAndSizes(dock
, pane_positions
, pane_sizes
); 
2212             for (j 
= 0; j 
< dock_pane_count
; ++j
) 
2214                 wxAuiPaneInfo
& pane 
= *(dock
.panes
.Item(j
)); 
2215                 pane
.dock_pos 
= pane_positions
[j
]; 
2217                 int amount 
= pane
.dock_pos 
- offset
; 
2221                     pane
.dock_pos 
+= -amount
; 
2223                 offset 
+= pane_sizes
[j
]; 
2228     // discover the maximum dock layer 
2230     for (i 
= 0; i 
< dock_count
; ++i
) 
2231         max_layer 
= wxMax(max_layer
, docks
.Item(i
).dock_layer
); 
2234     // clear out uiparts 
2237     // create a bunch of box sizers, 
2238     // from the innermost level outwards. 
2239     wxSizer
* cont 
= NULL
; 
2240     wxSizer
* middle 
= NULL
; 
2244     for (layer 
= 0; layer 
<= max_layer
; ++layer
) 
2246         wxAuiDockInfoPtrArray arr
; 
2248         // find any docks in this layer 
2249         FindDocks(docks
, -1, layer
, -1, arr
); 
2251         // if there aren't any, skip to the next layer 
2255         wxSizer
* old_cont 
= cont
; 
2257         // create a container which will hold this layer's 
2258         // docks (top, bottom, left, right) 
2259         cont 
= new wxBoxSizer(wxVERTICAL
); 
2262         // find any top docks in this layer 
2263         FindDocks(docks
, wxAUI_DOCK_TOP
, layer
, -1, arr
); 
2266             for (row 
= 0, row_count 
= arr
.GetCount(); row 
< row_count
; ++row
) 
2267                 LayoutAddDock(cont
, *arr
.Item(row
), uiparts
, spacer_only
); 
2271         // fill out the middle layer (which consists 
2272         // of left docks, content area and right docks) 
2274         middle 
= new wxBoxSizer(wxHORIZONTAL
); 
2276         // find any left docks in this layer 
2277         FindDocks(docks
, wxAUI_DOCK_LEFT
, layer
, -1, arr
); 
2280             for (row 
= 0, row_count 
= arr
.GetCount(); row 
< row_count
; ++row
) 
2281                 LayoutAddDock(middle
, *arr
.Item(row
), uiparts
, spacer_only
); 
2284         // add content dock (or previous layer's sizer 
2288             // find any center docks 
2289             FindDocks(docks
, wxAUI_DOCK_CENTER
, -1, -1, arr
); 
2292                 for (row 
= 0,row_count 
= arr
.GetCount(); row
<row_count
; ++row
) 
2293                    LayoutAddDock(middle
, *arr
.Item(row
), uiparts
, spacer_only
); 
2295             else if (!m_has_maximized
) 
2297                 // there are no center docks, add a background area 
2298                 wxSizerItem
* sizer_item 
= middle
->Add(1,1, 1, wxEXPAND
); 
2299                 wxAuiDockUIPart part
; 
2300                 part
.type 
= wxAuiDockUIPart::typeBackground
; 
2304                 part
.cont_sizer 
= middle
; 
2305                 part
.sizer_item 
= sizer_item
; 
2311             middle
->Add(old_cont
, 1, wxEXPAND
); 
2314         // find any right docks in this layer 
2315         FindDocks(docks
, wxAUI_DOCK_RIGHT
, layer
, -1, arr
); 
2318             for (row 
= arr
.GetCount()-1; row 
>= 0; --row
) 
2319                 LayoutAddDock(middle
, *arr
.Item(row
), uiparts
, spacer_only
); 
2322         if (middle
->GetChildren().GetCount() > 0) 
2323             cont
->Add(middle
, 1, wxEXPAND
); 
2329         // find any bottom docks in this layer 
2330         FindDocks(docks
, wxAUI_DOCK_BOTTOM
, layer
, -1, arr
); 
2333             for (row 
= arr
.GetCount()-1; row 
>= 0; --row
) 
2334                 LayoutAddDock(cont
, *arr
.Item(row
), uiparts
, spacer_only
); 
2341         // no sizer available, because there are no docks, 
2342         // therefore we will create a simple background area 
2343         cont 
= new wxBoxSizer(wxVERTICAL
); 
2344         wxSizerItem
* sizer_item 
= cont
->Add(1,1, 1, wxEXPAND
); 
2345         wxAuiDockUIPart part
; 
2346         part
.type 
= wxAuiDockUIPart::typeBackground
; 
2350         part
.cont_sizer 
= middle
; 
2351         part
.sizer_item 
= sizer_item
; 
2355     container
->Add(cont
, 1, wxEXPAND
); 
2360 // SetDockSizeConstraint() allows the dock constraints to be set.  For example, 
2361 // specifying values of 0.5, 0.5 will mean that upon dock creation, a dock may 
2362 // not be larger than half of the window's size 
2364 void wxAuiManager::SetDockSizeConstraint(double width_pct
, double height_pct
) 
2366     m_dock_constraint_x 
= wxMax(0.0, wxMin(1.0, width_pct
)); 
2367     m_dock_constraint_y 
= wxMax(0.0, wxMin(1.0, height_pct
)); 
2370 void wxAuiManager::GetDockSizeConstraint(double* width_pct
, double* height_pct
) const 
2373         *width_pct 
= m_dock_constraint_x
; 
2376         *height_pct 
= m_dock_constraint_y
; 
2381 // Update() updates the layout.  Whenever changes are made to 
2382 // one or more panes, this function should be called.  It is the 
2383 // external entry point for running the layout engine. 
2385 void wxAuiManager::Update() 
2387     m_hover_button 
= NULL
; 
2390     int i
, pane_count 
= m_panes
.GetCount(); 
2393     // destroy floating panes which have been 
2394     // redocked or are becoming non-floating 
2395     for (i 
= 0; i 
< pane_count
; ++i
) 
2397         wxAuiPaneInfo
& p 
= m_panes
.Item(i
); 
2399         if (!p
.IsFloating() && p
.frame
) 
2401             // because the pane is no longer in a floating, we need to 
2402             // reparent it to m_frame and destroy the floating frame 
2405             p
.window
->SetSize(1,1); 
2408             // the following block is a workaround for bug #1531361 
2409             // (see wxWidgets sourceforge page).  On wxGTK (only), when 
2410             // a frame is shown/hidden, a move event unfortunately 
2411             // also gets fired.  Because we may be dragging around 
2412             // a pane, we need to cancel that action here to prevent 
2413             // a spurious crash. 
2414             if (m_action_window 
== p
.frame
) 
2416                 if (wxWindow::GetCapture() == m_frame
) 
2417                     m_frame
->ReleaseMouse(); 
2418                 m_action 
= actionNone
; 
2419                 m_action_window 
= NULL
; 
2423             if (p
.frame
->IsShown()) 
2424                 p
.frame
->Show(false); 
2426             // reparent to m_frame and destroy the pane 
2427             if (m_action_window 
== p
.frame
) 
2429                 m_action_window 
= NULL
; 
2432             p
.window
->Reparent(m_frame
); 
2433             p
.frame
->SetSizer(NULL
); 
2440     // delete old sizer first 
2441     m_frame
->SetSizer(NULL
); 
2443     // create a layout for all of the panes 
2444     sizer 
= LayoutAll(m_panes
, m_docks
, m_uiparts
, false); 
2446     // hide or show panes as necessary, 
2447     // and float panes as necessary 
2448     for (i 
= 0; i 
< pane_count
; ++i
) 
2450         wxAuiPaneInfo
& p 
= m_panes
.Item(i
); 
2454             if (p
.frame 
== NULL
) 
2456                 // we need to create a frame for this 
2457                 // pane, which has recently been floated 
2458                 wxAuiFloatingFrame
* frame 
= CreateFloatingFrame(m_frame
, p
); 
2460                 // on MSW and Mac, if the owner desires transparent dragging, and 
2461                 // the dragging is happening right now, then the floating 
2462                 // window should have this style by default 
2463                 if (m_action 
== actionDragFloatingPane 
&& 
2464                     (m_flags 
& wxAUI_MGR_TRANSPARENT_DRAG
)) 
2465                         frame
->SetTransparent(150); 
2467                 frame
->SetPaneWindow(p
); 
2470                 if (p
.IsShown() && !frame
->IsShown()) 
2475                 // frame already exists, make sure it's position 
2476                 // and size reflect the information in wxAuiPaneInfo 
2477                 if ((p
.frame
->GetPosition() != p
.floating_pos
) || (p
.frame
->GetSize() != p
.floating_size
)) 
2479                     p
.frame
->SetSize(p
.floating_pos
.x
, p
.floating_pos
.y
, 
2480                                      p
.floating_size
.x
, p
.floating_size
.y
, 
2481                                      wxSIZE_USE_EXISTING
); 
2483                     p.frame->SetSize(p.floating_pos.x, p.floating_pos.y, 
2484                                      wxDefaultCoord, wxDefaultCoord, 
2485                                      wxSIZE_USE_EXISTING); 
2486                     //p.frame->Move(p.floating_pos.x, p.floating_pos.y); 
2490                 if (p
.frame
->IsShown() != p
.IsShown()) 
2491                     p
.frame
->Show(p
.IsShown()); 
2496             if (p
.window
->IsShown() != p
.IsShown()) 
2497                 p
.window
->Show(p
.IsShown()); 
2500         // if "active panes" are no longer allowed, clear 
2501         // any optionActive values from the pane states 
2502         if ((m_flags 
& wxAUI_MGR_ALLOW_ACTIVE_PANE
) == 0) 
2504             p
.state 
&= ~wxAuiPaneInfo::optionActive
; 
2509     // keep track of the old window rectangles so we can 
2510     // refresh those windows whose rect has changed 
2511     wxAuiRectArray old_pane_rects
; 
2512     for (i 
= 0; i 
< pane_count
; ++i
) 
2515         wxAuiPaneInfo
& p 
= m_panes
.Item(i
); 
2517         if (p
.window 
&& p
.IsShown() && p
.IsDocked()) 
2520         old_pane_rects
.Add(r
); 
2526     // apply the new sizer 
2527     m_frame
->SetSizer(sizer
); 
2528     m_frame
->SetAutoLayout(false); 
2533     // now that the frame layout is done, we need to check 
2534     // the new pane rectangles against the old rectangles that 
2535     // we saved a few lines above here.  If the rectangles have 
2536     // changed, the corresponding panes must also be updated 
2537     for (i 
= 0; i 
< pane_count
; ++i
) 
2539         wxAuiPaneInfo
& p 
= m_panes
.Item(i
); 
2540         if (p
.window 
&& p
.window
->IsShown() && p
.IsDocked()) 
2542             if (p
.rect 
!= old_pane_rects
[i
]) 
2544                 p
.window
->Refresh(); 
2553     // set frame's minimum size 
2556     // N.B. More work needs to be done on frame minimum sizes; 
2557     // this is some intresting code that imposes the minimum size, 
2558     // but we may want to include a more flexible mechanism or 
2559     // options for multiple minimum-size modes, e.g. strict or lax 
2560     wxSize min_size = sizer->GetMinSize(); 
2561     wxSize frame_size = m_frame->GetSize(); 
2562     wxSize client_size = m_frame->GetClientSize(); 
2564     wxSize minframe_size(min_size.x+frame_size.x-client_size.x, 
2565                          min_size.y+frame_size.y-client_size.y ); 
2567     m_frame->SetMinSize(minframe_size); 
2569     if (frame_size.x < minframe_size.x || 
2570         frame_size.y < minframe_size.y) 
2571             sizer->Fit(m_frame); 
2576 // DoFrameLayout() is an internal function which invokes wxSizer::Layout 
2577 // on the frame's main sizer, then measures all the various UI items 
2578 // and updates their internal rectangles.  This should always be called 
2579 // instead of calling m_frame->Layout() directly 
2581 void wxAuiManager::DoFrameLayout() 
2586     for (i 
= 0, part_count 
= m_uiparts
.GetCount(); i 
< part_count
; ++i
) 
2588         wxAuiDockUIPart
& part 
= m_uiparts
.Item(i
); 
2590         // get the rectangle of the UI part 
2591         // originally, this code looked like this: 
2592         //    part.rect = wxRect(part.sizer_item->GetPosition(), 
2593         //                       part.sizer_item->GetSize()); 
2594         // this worked quite well, with one exception: the mdi 
2595         // client window had a "deferred" size variable 
2596         // that returned the wrong size.  It looks like 
2597         // a bug in wx, because the former size of the window 
2598         // was being returned.  So, we will retrieve the part's 
2599         // rectangle via other means 
2602         part
.rect 
= part
.sizer_item
->GetRect(); 
2603         int flag 
= part
.sizer_item
->GetFlag(); 
2604         int border 
= part
.sizer_item
->GetBorder(); 
2607             part
.rect
.y 
-= border
; 
2608             part
.rect
.height 
+= border
; 
2612             part
.rect
.x 
-= border
; 
2613             part
.rect
.width 
+= border
; 
2615         if (flag 
& wxBOTTOM
) 
2616             part
.rect
.height 
+= border
; 
2618             part
.rect
.width 
+= border
; 
2621         if (part
.type 
== wxAuiDockUIPart::typeDock
) 
2622             part
.dock
->rect 
= part
.rect
; 
2623         if (part
.type 
== wxAuiDockUIPart::typePane
) 
2624             part
.pane
->rect 
= part
.rect
; 
2628 // GetPanePart() looks up the pane the pane border UI part (or the regular 
2629 // pane part if there is no border). This allows the caller to get the exact 
2630 // rectangle of the pane in question, including decorations like 
2631 // caption and border (if any). 
2633 wxAuiDockUIPart
* wxAuiManager::GetPanePart(wxWindow
* wnd
) 
2636     for (i 
= 0, part_count 
= m_uiparts
.GetCount(); i 
< part_count
; ++i
) 
2638         wxAuiDockUIPart
& part 
= m_uiparts
.Item(i
); 
2639         if (part
.type 
== wxAuiDockUIPart::typePaneBorder 
&& 
2640             part
.pane 
&& part
.pane
->window 
== wnd
) 
2643     for (i 
= 0, part_count 
= m_uiparts
.GetCount(); i 
< part_count
; ++i
) 
2645         wxAuiDockUIPart
& part 
= m_uiparts
.Item(i
); 
2646         if (part
.type 
== wxAuiDockUIPart::typePane 
&& 
2647             part
.pane 
&& part
.pane
->window 
== wnd
) 
2655 // GetDockPixelOffset() is an internal function which returns 
2656 // a dock's offset in pixels from the left side of the window 
2657 // (for horizontal docks) or from the top of the window (for 
2658 // vertical docks).  This value is necessary for calculating 
2659 // fixel-pane/toolbar offsets when they are dragged. 
2661 int wxAuiManager::GetDockPixelOffset(wxAuiPaneInfo
& test
) 
2663     // the only way to accurately calculate the dock's 
2664     // offset is to actually run a theoretical layout 
2666     int i
, part_count
, dock_count
; 
2667     wxAuiDockInfoArray docks
; 
2668     wxAuiPaneInfoArray panes
; 
2669     wxAuiDockUIPartArray uiparts
; 
2670     CopyDocksAndPanes(docks
, panes
, m_docks
, m_panes
); 
2673     wxSizer
* sizer 
= LayoutAll(panes
, docks
, uiparts
, true); 
2674     wxSize client_size 
= m_frame
->GetClientSize(); 
2675     sizer
->SetDimension(0, 0, client_size
.x
, client_size
.y
); 
2678     for (i 
= 0, part_count 
= uiparts
.GetCount(); i 
< part_count
; ++i
) 
2680         wxAuiDockUIPart
& part 
= uiparts
.Item(i
); 
2681         part
.rect 
= wxRect(part
.sizer_item
->GetPosition(), 
2682                            part
.sizer_item
->GetSize()); 
2683         if (part
.type 
== wxAuiDockUIPart::typeDock
) 
2684             part
.dock
->rect 
= part
.rect
; 
2689     for (i 
= 0, dock_count 
= docks
.GetCount(); i 
< dock_count
; ++i
) 
2691         wxAuiDockInfo
& dock 
= docks
.Item(i
); 
2692         if (test
.dock_direction 
== dock
.dock_direction 
&& 
2693             test
.dock_layer
==dock
.dock_layer 
&& test
.dock_row
==dock
.dock_row
) 
2695             if (dock
.IsVertical()) 
2707 // ProcessDockResult() is a utility function used by DoDrop() - it checks 
2708 // if a dock operation is allowed, the new dock position is copied into 
2709 // the target info.  If the operation was allowed, the function returns true. 
2711 bool wxAuiManager::ProcessDockResult(wxAuiPaneInfo
& target
, 
2712                                      const wxAuiPaneInfo
& new_pos
) 
2714     bool allowed 
= false; 
2715     switch (new_pos
.dock_direction
) 
2717         case wxAUI_DOCK_TOP
:    allowed 
= target
.IsTopDockable();    break; 
2718         case wxAUI_DOCK_BOTTOM
: allowed 
= target
.IsBottomDockable(); break; 
2719         case wxAUI_DOCK_LEFT
:   allowed 
= target
.IsLeftDockable();   break; 
2720         case wxAUI_DOCK_RIGHT
:  allowed 
= target
.IsRightDockable();  break; 
2730 // DoDrop() is an important function.  It basically takes a mouse position, 
2731 // and determines where the pane's new position would be.  If the pane is to be 
2732 // dropped, it performs the drop operation using the specified dock and pane 
2733 // arrays.  By specifying copied dock and pane arrays when calling, a "what-if" 
2734 // scenario can be performed, giving precise coordinates for drop hints. 
2735 // If, however, wxAuiManager:m_docks and wxAuiManager::m_panes are specified 
2736 // as parameters, the changes will be made to the main state arrays 
2738 const int auiInsertRowPixels 
= 10; 
2739 const int auiNewRowPixels 
= 40; 
2740 const int auiLayerInsertPixels 
= 40; 
2741 const int auiLayerInsertOffset 
= 5; 
2743 bool wxAuiManager::DoDrop(wxAuiDockInfoArray
& docks
, 
2744                           wxAuiPaneInfoArray
& panes
, 
2745                           wxAuiPaneInfo
& target
, 
2747                           const wxPoint
& offset
) 
2749     wxSize cli_size 
= m_frame
->GetClientSize(); 
2751     wxAuiPaneInfo drop 
= target
; 
2754     // The result should always be shown 
2758     // Check to see if the pane has been dragged outside of the window 
2759     // (or near to the outside of the window), if so, dock it along the edge 
2762     int layer_insert_offset 
= auiLayerInsertOffset
; 
2763     if (drop
.IsToolbar()) 
2764         layer_insert_offset 
= 0; 
2767     if (pt
.x 
< layer_insert_offset 
&& 
2768         pt
.x 
> layer_insert_offset
-auiLayerInsertPixels
) 
2770         int new_layer 
= wxMax(wxMax(GetMaxLayer(docks
, wxAUI_DOCK_LEFT
), 
2771                                 GetMaxLayer(docks
, wxAUI_DOCK_BOTTOM
)), 
2772                                 GetMaxLayer(docks
, wxAUI_DOCK_TOP
)) + 1; 
2774         if (drop
.IsToolbar()) 
2775             new_layer 
= auiToolBarLayer
; 
2780              Position(pt
.y 
- GetDockPixelOffset(drop
) - offset
.y
); 
2781         return ProcessDockResult(target
, drop
); 
2783     else if (pt
.y 
< layer_insert_offset 
&& 
2784              pt
.y 
> layer_insert_offset
-auiLayerInsertPixels
) 
2786         int new_layer 
= wxMax(wxMax(GetMaxLayer(docks
, wxAUI_DOCK_TOP
), 
2787                                 GetMaxLayer(docks
, wxAUI_DOCK_LEFT
)), 
2788                                 GetMaxLayer(docks
, wxAUI_DOCK_RIGHT
)) + 1; 
2790         if (drop
.IsToolbar()) 
2791             new_layer 
= auiToolBarLayer
; 
2796              Position(pt
.x 
- GetDockPixelOffset(drop
) - offset
.x
); 
2797         return ProcessDockResult(target
, drop
); 
2799     else if (pt
.x 
>= cli_size
.x 
- layer_insert_offset 
&& 
2800              pt
.x 
< cli_size
.x 
- layer_insert_offset 
+ auiLayerInsertPixels
) 
2802         int new_layer 
= wxMax(wxMax(GetMaxLayer(docks
, wxAUI_DOCK_RIGHT
), 
2803                                 GetMaxLayer(docks
, wxAUI_DOCK_TOP
)), 
2804                                 GetMaxLayer(docks
, wxAUI_DOCK_BOTTOM
)) + 1; 
2806         if (drop
.IsToolbar()) 
2807             new_layer 
= auiToolBarLayer
; 
2809         drop
.Dock().Right(). 
2812              Position(pt
.y 
- GetDockPixelOffset(drop
) - offset
.y
); 
2813         return ProcessDockResult(target
, drop
); 
2815     else if (pt
.y 
>= cli_size
.y 
- layer_insert_offset 
&& 
2816              pt
.y 
< cli_size
.y 
- layer_insert_offset 
+ auiLayerInsertPixels
) 
2818         int new_layer 
= wxMax( wxMax( GetMaxLayer(docks
, wxAUI_DOCK_BOTTOM
), 
2819                                       GetMaxLayer(docks
, wxAUI_DOCK_LEFT
)), 
2820                                       GetMaxLayer(docks
, wxAUI_DOCK_RIGHT
)) + 1; 
2822         if (drop
.IsToolbar()) 
2823             new_layer 
= auiToolBarLayer
; 
2825         drop
.Dock().Bottom(). 
2828              Position(pt
.x 
- GetDockPixelOffset(drop
) - offset
.x
); 
2829         return ProcessDockResult(target
, drop
); 
2833     wxAuiDockUIPart
* part 
= HitTest(pt
.x
, pt
.y
); 
2836     if (drop
.IsToolbar()) 
2838         if (!part 
|| !part
->dock
) 
2841         // calculate the offset from where the dock begins 
2842         // to the point where the user dropped the pane 
2843         int dock_drop_offset 
= 0; 
2844         if (part
->dock
->IsHorizontal()) 
2845             dock_drop_offset 
= pt
.x 
- part
->dock
->rect
.x 
- offset
.x
; 
2847             dock_drop_offset 
= pt
.y 
- part
->dock
->rect
.y 
- offset
.y
; 
2850         // toolbars may only be moved in and to fixed-pane docks, 
2851         // otherwise we will try to float the pane.  Also, the pane 
2852         // should float if being dragged over center pane windows 
2853         if (!part
->dock
->fixed 
|| part
->dock
->dock_direction 
== wxAUI_DOCK_CENTER
) 
2855             if (m_last_rect
.IsEmpty() || m_last_rect
.Contains(pt
.x
, pt
.y 
)) 
2861                 if ((m_flags 
& wxAUI_MGR_ALLOW_FLOATING
) && 
2862                    (drop
.IsFloatable() || 
2863                     (part
->dock
->dock_direction 
!= wxAUI_DOCK_CENTER 
&& 
2864                      part
->dock
->dock_direction 
!= wxAUI_DOCK_NONE
))) 
2871                 return ProcessDockResult(target
, drop
); 
2874             drop
.Position(pt
.x 
- GetDockPixelOffset(drop
) - offset
.x
); 
2876             return ProcessDockResult(target
, drop
); 
2881         m_last_rect 
= part
->dock
->rect
; 
2882         m_last_rect
.Inflate( 15, 15 ); 
2885              Direction(part
->dock
->dock_direction
). 
2886              Layer(part
->dock
->dock_layer
). 
2887              Row(part
->dock
->dock_row
). 
2888              Position(dock_drop_offset
); 
2891             ((pt
.y 
< part
->dock
->rect
.y 
+ 1) && part
->dock
->IsHorizontal()) || 
2892             ((pt
.x 
< part
->dock
->rect
.x 
+ 1) && part
->dock
->IsVertical()) 
2893             ) && part
->dock
->panes
.GetCount() > 1) 
2895             if ((part
->dock
->dock_direction 
== wxAUI_DOCK_TOP
) || 
2896                 (part
->dock
->dock_direction 
== wxAUI_DOCK_LEFT
)) 
2898                 int row 
= drop
.dock_row
; 
2899                 DoInsertDockRow(panes
, part
->dock
->dock_direction
, 
2900                                 part
->dock
->dock_layer
, 
2901                                 part
->dock
->dock_row
); 
2902                 drop
.dock_row 
= row
; 
2906                 DoInsertDockRow(panes
, part
->dock
->dock_direction
, 
2907                                 part
->dock
->dock_layer
, 
2908                                 part
->dock
->dock_row
+1); 
2909                 drop
.dock_row 
= part
->dock
->dock_row
+1; 
2914             ((pt
.y 
> part
->dock
->rect
.y 
+ part
->dock
->rect
.height 
- 2 ) && part
->dock
->IsHorizontal()) || 
2915             ((pt
.x 
> part
->dock
->rect
.x 
+ part
->dock
->rect
.width 
- 2 ) && part
->dock
->IsVertical()) 
2916             ) && part
->dock
->panes
.GetCount() > 1) 
2918             if ((part
->dock
->dock_direction 
== wxAUI_DOCK_TOP
) || 
2919                 (part
->dock
->dock_direction 
== wxAUI_DOCK_LEFT
)) 
2921                 DoInsertDockRow(panes
, part
->dock
->dock_direction
, 
2922                                 part
->dock
->dock_layer
, 
2923                                 part
->dock
->dock_row
+1); 
2924                 drop
.dock_row 
= part
->dock
->dock_row
+1; 
2928                 int row 
= drop
.dock_row
; 
2929                 DoInsertDockRow(panes
, part
->dock
->dock_direction
, 
2930                                 part
->dock
->dock_layer
, 
2931                                 part
->dock
->dock_row
); 
2932                 drop
.dock_row 
= row
; 
2936         return ProcessDockResult(target
, drop
); 
2945     if (part
->type 
== wxAuiDockUIPart::typePaneBorder 
|| 
2946         part
->type 
== wxAuiDockUIPart::typeCaption 
|| 
2947         part
->type 
== wxAuiDockUIPart::typeGripper 
|| 
2948         part
->type 
== wxAuiDockUIPart::typePaneButton 
|| 
2949         part
->type 
== wxAuiDockUIPart::typePane 
|| 
2950         part
->type 
== wxAuiDockUIPart::typePaneSizer 
|| 
2951         part
->type 
== wxAuiDockUIPart::typeDockSizer 
|| 
2952         part
->type 
== wxAuiDockUIPart::typeBackground
) 
2954         if (part
->type 
== wxAuiDockUIPart::typeDockSizer
) 
2956             if (part
->dock
->panes
.GetCount() != 1) 
2958             part 
= GetPanePart(part
->dock
->panes
.Item(0)->window
); 
2965         // If a normal frame is being dragged over a toolbar, insert it 
2966         // along the edge under the toolbar, but over all other panes. 
2967         // (this could be done much better, but somehow factoring this 
2968         // calculation with the one at the beginning of this function) 
2969         if (part
->dock 
&& part
->dock
->toolbar
) 
2973             switch (part
->dock
->dock_direction
) 
2975                 case wxAUI_DOCK_LEFT
: 
2976                     layer 
= wxMax(wxMax(GetMaxLayer(docks
, wxAUI_DOCK_LEFT
), 
2977                                       GetMaxLayer(docks
, wxAUI_DOCK_BOTTOM
)), 
2978                                       GetMaxLayer(docks
, wxAUI_DOCK_TOP
)); 
2980                 case wxAUI_DOCK_TOP
: 
2981                     layer 
= wxMax(wxMax(GetMaxLayer(docks
, wxAUI_DOCK_TOP
), 
2982                                       GetMaxLayer(docks
, wxAUI_DOCK_LEFT
)), 
2983                                       GetMaxLayer(docks
, wxAUI_DOCK_RIGHT
)); 
2985                 case wxAUI_DOCK_RIGHT
: 
2986                     layer 
= wxMax(wxMax(GetMaxLayer(docks
, wxAUI_DOCK_RIGHT
), 
2987                                       GetMaxLayer(docks
, wxAUI_DOCK_TOP
)), 
2988                                       GetMaxLayer(docks
, wxAUI_DOCK_BOTTOM
)); 
2990                 case wxAUI_DOCK_BOTTOM
: 
2991                     layer 
= wxMax(wxMax(GetMaxLayer(docks
, wxAUI_DOCK_BOTTOM
), 
2992                                       GetMaxLayer(docks
, wxAUI_DOCK_LEFT
)), 
2993                                       GetMaxLayer(docks
, wxAUI_DOCK_RIGHT
)); 
2997             DoInsertDockRow(panes
, part
->dock
->dock_direction
, 
3000                  Direction(part
->dock
->dock_direction
). 
3001                  Layer(layer
).Row(0).Position(0); 
3002             return ProcessDockResult(target
, drop
); 
3009         part 
= GetPanePart(part
->pane
->window
); 
3013         bool insert_dock_row 
= false; 
3014         int insert_row 
= part
->pane
->dock_row
; 
3015         int insert_dir 
= part
->pane
->dock_direction
; 
3016         int insert_layer 
= part
->pane
->dock_layer
; 
3018         switch (part
->pane
->dock_direction
) 
3020             case wxAUI_DOCK_TOP
: 
3021                 if (pt
.y 
>= part
->rect
.y 
&& 
3022                     pt
.y 
< part
->rect
.y
+auiInsertRowPixels
) 
3023                         insert_dock_row 
= true; 
3025             case wxAUI_DOCK_BOTTOM
: 
3026                 if (pt
.y 
> part
->rect
.y
+part
->rect
.height
-auiInsertRowPixels 
&& 
3027                     pt
.y 
<= part
->rect
.y 
+ part
->rect
.height
) 
3028                         insert_dock_row 
= true; 
3030             case wxAUI_DOCK_LEFT
: 
3031                 if (pt
.x 
>= part
->rect
.x 
&& 
3032                     pt
.x 
< part
->rect
.x
+auiInsertRowPixels
) 
3033                         insert_dock_row 
= true; 
3035             case wxAUI_DOCK_RIGHT
: 
3036                 if (pt
.x 
> part
->rect
.x
+part
->rect
.width
-auiInsertRowPixels 
&& 
3037                     pt
.x 
<= part
->rect
.x
+part
->rect
.width
) 
3038                         insert_dock_row 
= true; 
3040             case wxAUI_DOCK_CENTER
: 
3042                 // "new row pixels" will be set to the default, but 
3043                 // must never exceed 20% of the window size 
3044                 int new_row_pixels_x 
= auiNewRowPixels
; 
3045                 int new_row_pixels_y 
= auiNewRowPixels
; 
3047                 if (new_row_pixels_x 
> (part
->rect
.width
*20)/100) 
3048                     new_row_pixels_x 
= (part
->rect
.width
*20)/100; 
3050                 if (new_row_pixels_y 
> (part
->rect
.height
*20)/100) 
3051                     new_row_pixels_y 
= (part
->rect
.height
*20)/100; 
3054                 // determine if the mouse pointer is in a location that 
3055                 // will cause a new row to be inserted.  The hot spot positions 
3056                 // are along the borders of the center pane 
3059                 insert_dock_row 
= true; 
3060                 const wxRect
& pr 
= part
->rect
; 
3061                 if (pt
.x 
>= pr
.x 
&& pt
.x 
< pr
.x 
+ new_row_pixels_x
) 
3062                     insert_dir 
= wxAUI_DOCK_LEFT
; 
3063                 else if (pt
.y 
>= pr
.y 
&& pt
.y 
< pr
.y 
+ new_row_pixels_y
) 
3064                     insert_dir 
= wxAUI_DOCK_TOP
; 
3065                 else if (pt
.x 
>= pr
.x 
+ pr
.width 
- new_row_pixels_x 
&& 
3066                          pt
.x 
< pr
.x 
+ pr
.width
) 
3067                     insert_dir 
= wxAUI_DOCK_RIGHT
; 
3068                 else if (pt
.y 
>= pr
.y
+ pr
.height 
- new_row_pixels_y 
&& 
3069                          pt
.y 
< pr
.y 
+ pr
.height
) 
3070                     insert_dir 
= wxAUI_DOCK_BOTTOM
; 
3074                 insert_row 
= GetMaxRow(panes
, insert_dir
, insert_layer
) + 1; 
3078         if (insert_dock_row
) 
3080             DoInsertDockRow(panes
, insert_dir
, insert_layer
, insert_row
); 
3081             drop
.Dock().Direction(insert_dir
). 
3082                         Layer(insert_layer
). 
3085             return ProcessDockResult(target
, drop
); 
3088         // determine the mouse offset and the pane size, both in the 
3089         // direction of the dock itself, and perpendicular to the dock 
3093         if (part
->orientation 
== wxVERTICAL
) 
3095             offset 
= pt
.y 
- part
->rect
.y
; 
3096             size 
= part
->rect
.GetHeight(); 
3100             offset 
= pt
.x 
- part
->rect
.x
; 
3101             size 
= part
->rect
.GetWidth(); 
3104         int drop_position 
= part
->pane
->dock_pos
; 
3106         // if we are in the top/left part of the pane, 
3107         // insert the pane before the pane being hovered over 
3108         if (offset 
<= size
/2) 
3110             drop_position 
= part
->pane
->dock_pos
; 
3112                          part
->pane
->dock_direction
, 
3113                          part
->pane
->dock_layer
, 
3114                          part
->pane
->dock_row
, 
3115                          part
->pane
->dock_pos
); 
3118         // if we are in the bottom/right part of the pane, 
3119         // insert the pane before the pane being hovered over 
3120         if (offset 
> size
/2) 
3122             drop_position 
= part
->pane
->dock_pos
+1; 
3124                          part
->pane
->dock_direction
, 
3125                          part
->pane
->dock_layer
, 
3126                          part
->pane
->dock_row
, 
3127                          part
->pane
->dock_pos
+1); 
3131              Direction(part
->dock
->dock_direction
). 
3132              Layer(part
->dock
->dock_layer
). 
3133              Row(part
->dock
->dock_row
). 
3134              Position(drop_position
); 
3135         return ProcessDockResult(target
, drop
); 
3142 void wxAuiManager::OnHintFadeTimer(wxTimerEvent
& WXUNUSED(event
)) 
3144     if (!m_hint_wnd 
|| m_hint_fadeamt 
>= m_hint_fademax
) 
3146         m_hint_fadetimer
.Stop(); 
3150     m_hint_fadeamt 
+= 4; 
3151     m_hint_wnd
->SetTransparent(m_hint_fadeamt
); 
3154 void wxAuiManager::ShowHint(const wxRect
& rect
) 
3158         // if the hint rect is the same as last time, don't do anything 
3159         if (m_last_hint 
== rect
) 
3163         m_hint_fadeamt 
= m_hint_fademax
; 
3165         if ((m_flags 
& wxAUI_MGR_HINT_FADE
) 
3166             && !((m_hint_wnd
->IsKindOf(CLASSINFO(wxPseudoTransparentFrame
))) && 
3167                  (m_flags 
& wxAUI_MGR_NO_VENETIAN_BLINDS_FADE
)) 
3171         m_hint_wnd
->SetSize(rect
); 
3172         m_hint_wnd
->SetTransparent(m_hint_fadeamt
); 
3174         if (!m_hint_wnd
->IsShown()) 
3177         // if we are dragging a floating pane, set the focus 
3178         // back to that floating pane (otherwise it becomes unfocused) 
3179         if (m_action 
== actionDragFloatingPane 
&& m_action_window
) 
3180             m_action_window
->SetFocus(); 
3182         m_hint_wnd
->Raise(); 
3185         if (m_hint_fadeamt 
!= m_hint_fademax
) //  Only fade if we need to 
3187             // start fade in timer 
3188             m_hint_fadetimer
.SetOwner(this, 101); 
3189             m_hint_fadetimer
.Start(5); 
3192     else  // Not using a transparent hint window... 
3194         if (!(m_flags 
& wxAUI_MGR_RECTANGLE_HINT
)) 
3197         if (m_last_hint 
!= rect
) 
3199             // remove the last hint rectangle 
3205         wxScreenDC screendc
; 
3206         wxRegion 
clip(1, 1, 10000, 10000); 
3208         // clip all floating windows, so we don't draw over them 
3210         for (i 
= 0, pane_count 
= m_panes
.GetCount(); i 
< pane_count
; ++i
) 
3212             wxAuiPaneInfo
& pane 
= m_panes
.Item(i
); 
3214             if (pane
.IsFloating() && 
3215                 pane
.frame
->IsShown()) 
3217                 wxRect rect 
= pane
.frame
->GetRect(); 
3219                 // wxGTK returns the client size, not the whole frame size 
3225                 clip
.Subtract(rect
); 
3229         // As we can only hide the hint by redrawing the managed window, we 
3230         // need to clip the region to the managed window too or we get 
3231         // nasty redrawn problems. 
3232         clip
.Intersect(m_frame
->GetRect()); 
3234         screendc
.SetDeviceClippingRegion(clip
); 
3236         wxBitmap stipple 
= wxPaneCreateStippleBitmap(); 
3237         wxBrush 
brush(stipple
); 
3238         screendc
.SetBrush(brush
); 
3239         screendc
.SetPen(*wxTRANSPARENT_PEN
); 
3241         screendc
.DrawRectangle(rect
.x
, rect
.y
, 5, rect
.height
); 
3242         screendc
.DrawRectangle(rect
.x
+5, rect
.y
, rect
.width
-10, 5); 
3243         screendc
.DrawRectangle(rect
.x
+rect
.width
-5, rect
.y
, 5, rect
.height
); 
3244         screendc
.DrawRectangle(rect
.x
+5, rect
.y
+rect
.height
-5, rect
.width
-10, 5); 
3248 void wxAuiManager::HideHint() 
3250     // hides a transparent window hint, if there is one 
3253         if (m_hint_wnd
->IsShown()) 
3254             m_hint_wnd
->Show(false); 
3255         m_hint_wnd
->SetTransparent(0); 
3256         m_hint_fadetimer
.Stop(); 
3257         m_last_hint 
= wxRect(); 
3261     // hides a painted hint by redrawing the frame window 
3262     if (!m_last_hint
.IsEmpty()) 
3266         m_last_hint 
= wxRect(); 
3272 void wxAuiManager::StartPaneDrag(wxWindow
* pane_window
, 
3273                                  const wxPoint
& offset
) 
3275     wxAuiPaneInfo
& pane 
= GetPane(pane_window
); 
3279     if (pane
.IsToolbar()) 
3281         m_action 
= actionDragToolbarPane
; 
3285         m_action 
= actionDragFloatingPane
; 
3288     m_action_window 
= pane_window
; 
3289     m_action_offset 
= offset
; 
3290     m_frame
->CaptureMouse(); 
3294 // CalculateHintRect() calculates the drop hint rectangle.  The method 
3295 // first calls DoDrop() to determine the exact position the pane would 
3296 // be at were if dropped.  If the pane would indeed become docked at the 
3297 // specified drop point, the the rectangle hint will be returned in 
3298 // screen coordinates.  Otherwise, an empty rectangle is returned. 
3299 // |pane_window| is the window pointer of the pane being dragged, |pt| is 
3300 // the mouse position, in client coordinates.  |offset| describes the offset 
3301 // that the mouse is from the upper-left corner of the item being dragged 
3303 wxRect 
wxAuiManager::CalculateHintRect(wxWindow
* pane_window
, 
3305                                        const wxPoint
& offset
) 
3309     // we need to paint a hint rectangle; to find out the exact hint rectangle, 
3310     // we will create a new temporary layout and then measure the resulting 
3311     // rectangle; we will create a copy of the docking structures (m_dock) 
3312     // so that we don't modify the real thing on screen 
3314     int i
, pane_count
, part_count
; 
3315     wxAuiDockInfoArray docks
; 
3316     wxAuiPaneInfoArray panes
; 
3317     wxAuiDockUIPartArray uiparts
; 
3318     wxAuiPaneInfo hint 
= GetPane(pane_window
); 
3319     hint
.name 
= wxT("__HINT__"); 
3320     hint
.PaneBorder(true); 
3326     CopyDocksAndPanes(docks
, panes
, m_docks
, m_panes
); 
3328     // remove any pane already there which bears the same window; 
3329     // this happens when you are moving a pane around in a dock 
3330     for (i 
= 0, pane_count 
= panes
.GetCount(); i 
< pane_count
; ++i
) 
3332         if (panes
.Item(i
).window 
== pane_window
) 
3334             RemovePaneFromDocks(docks
, panes
.Item(i
)); 
3340     // find out where the new pane would be 
3341     if (!DoDrop(docks
, panes
, hint
, pt
, offset
)) 
3348     wxSizer
* sizer 
= LayoutAll(panes
, docks
, uiparts
, true); 
3349     wxSize client_size 
= m_frame
->GetClientSize(); 
3350     sizer
->SetDimension(0, 0, client_size
.x
, client_size
.y
); 
3353     for (i 
= 0, part_count 
= uiparts
.GetCount(); 
3354          i 
< part_count
; ++i
) 
3356         wxAuiDockUIPart
& part 
= uiparts
.Item(i
); 
3358         if (part
.type 
== wxAuiDockUIPart::typePaneBorder 
&& 
3359             part
.pane 
&& part
.pane
->name 
== wxT("__HINT__")) 
3361             rect 
= wxRect(part
.sizer_item
->GetPosition(), 
3362                           part
.sizer_item
->GetSize()); 
3374     // actually show the hint rectangle on the screen 
3375     m_frame
->ClientToScreen(&rect
.x
, &rect
.y
); 
3377     if ( m_frame
->GetLayoutDirection() == wxLayout_RightToLeft 
) 
3379         // Mirror rectangle in RTL mode 
3380         rect
.x 
-= rect
.GetWidth(); 
3386 // DrawHintRect() calculates the hint rectangle by calling 
3387 // CalculateHintRect().  If there is a rectangle, it shows it 
3388 // by calling ShowHint(), otherwise it hides any hint 
3389 // rectangle currently shown 
3390 void wxAuiManager::DrawHintRect(wxWindow
* pane_window
, 
3392                                 const wxPoint
& offset
) 
3394     wxRect rect 
= CalculateHintRect(pane_window
, pt
, offset
); 
3406 void wxAuiManager::OnFloatingPaneMoveStart(wxWindow
* wnd
) 
3408     // try to find the pane 
3409     wxAuiPaneInfo
& pane 
= GetPane(wnd
); 
3410     wxASSERT_MSG(pane
.IsOk(), wxT("Pane window not found")); 
3412     if (m_flags 
& wxAUI_MGR_TRANSPARENT_DRAG
) 
3413         pane
.frame
->SetTransparent(150); 
3416 void wxAuiManager::OnFloatingPaneMoving(wxWindow
* wnd
, wxDirection dir
) 
3418     // try to find the pane 
3419     wxAuiPaneInfo
& pane 
= GetPane(wnd
); 
3420     wxASSERT_MSG(pane
.IsOk(), wxT("Pane window not found")); 
3422     wxPoint pt 
= ::wxGetMousePosition(); 
3425     // Adapt pt to direction 
3428         // move to pane's upper border 
3430         pos 
= wnd
->ClientToScreen( pos 
); 
3432         // and some more pixels for the title bar 
3435     else if (dir 
== wxWEST
) 
3437         // move to pane's left border 
3439         pos 
= wnd
->ClientToScreen( pos 
); 
3442     else if (dir 
== wxEAST
) 
3444         // move to pane's right border 
3445         wxPoint 
pos( wnd
->GetSize().x
, 0 ); 
3446         pos 
= wnd
->ClientToScreen( pos 
); 
3449     else if (dir 
== wxSOUTH
) 
3451         // move to pane's bottom border 
3452         wxPoint 
pos( 0, wnd
->GetSize().y 
); 
3453         pos 
= wnd
->ClientToScreen( pos 
); 
3460     wxPoint client_pt 
= m_frame
->ScreenToClient(pt
); 
3462     // calculate the offset from the upper left-hand corner 
3463     // of the frame to the mouse pointer 
3464     wxPoint frame_pos 
= pane
.frame
->GetPosition(); 
3465     wxPoint 
action_offset(pt
.x
-frame_pos
.x
, pt
.y
-frame_pos
.y
); 
3467     // no hint for toolbar floating windows 
3468     if (pane
.IsToolbar() && m_action 
== actionDragFloatingPane
) 
3470         wxAuiDockInfoArray docks
; 
3471         wxAuiPaneInfoArray panes
; 
3472         wxAuiDockUIPartArray uiparts
; 
3473         wxAuiPaneInfo hint 
= pane
; 
3475         CopyDocksAndPanes(docks
, panes
, m_docks
, m_panes
); 
3477         // find out where the new pane would be 
3478         if (!DoDrop(docks
, panes
, hint
, client_pt
)) 
3480         if (hint
.IsFloating()) 
3484         m_action 
= actionDragToolbarPane
; 
3485         m_action_window 
= pane
.window
; 
3493     // if a key modifier is pressed while dragging the frame, 
3494     // don't dock the window 
3495     if (!CanDockPanel(pane
)) 
3502     DrawHintRect(wnd
, client_pt
, action_offset
); 
3505     // this cleans up some screen artifacts that are caused on GTK because 
3506     // we aren't getting the exact size of the window (see comment 
3516 void wxAuiManager::OnFloatingPaneMoved(wxWindow
* wnd
, wxDirection dir
) 
3518     // try to find the pane 
3519     wxAuiPaneInfo
& pane 
= GetPane(wnd
); 
3520     wxASSERT_MSG(pane
.IsOk(), wxT("Pane window not found")); 
3522     wxPoint pt 
= ::wxGetMousePosition(); 
3525     // Adapt pt to direction 
3528         // move to pane's upper border 
3530         pos 
= wnd
->ClientToScreen( pos 
); 
3532         // and some more pixels for the title bar 
3535     else if (dir 
== wxWEST
) 
3537         // move to pane's left border 
3539         pos 
= wnd
->ClientToScreen( pos 
); 
3542     else if (dir 
== wxEAST
) 
3544         // move to pane's right border 
3545         wxPoint 
pos( wnd
->GetSize().x
, 0 ); 
3546         pos 
= wnd
->ClientToScreen( pos 
); 
3549     else if (dir 
== wxSOUTH
) 
3551         // move to pane's bottom border 
3552         wxPoint 
pos( 0, wnd
->GetSize().y 
); 
3553         pos 
= wnd
->ClientToScreen( pos 
); 
3560     wxPoint client_pt 
= m_frame
->ScreenToClient(pt
); 
3562     // calculate the offset from the upper left-hand corner 
3563     // of the frame to the mouse pointer 
3564     wxPoint frame_pos 
= pane
.frame
->GetPosition(); 
3565     wxPoint 
action_offset(pt
.x
-frame_pos
.x
, pt
.y
-frame_pos
.y
); 
3568     // if a key modifier is pressed while dragging the frame, 
3569     // don't dock the window 
3570     if (CanDockPanel(pane
)) 
3572         // do the drop calculation 
3573         DoDrop(m_docks
, m_panes
, pane
, client_pt
, action_offset
); 
3576     // if the pane is still floating, update it's floating 
3577     // position (that we store) 
3578     if (pane
.IsFloating()) 
3580         pane
.floating_pos 
= pane
.frame
->GetPosition(); 
3582         if (m_flags 
& wxAUI_MGR_TRANSPARENT_DRAG
) 
3583             pane
.frame
->SetTransparent(255); 
3585     else if (m_has_maximized
) 
3587         RestoreMaximizedPane(); 
3595 void wxAuiManager::OnFloatingPaneResized(wxWindow
* wnd
, const wxSize
& size
) 
3597     // try to find the pane 
3598     wxAuiPaneInfo
& pane 
= GetPane(wnd
); 
3599     wxASSERT_MSG(pane
.IsOk(), wxT("Pane window not found")); 
3601     pane
.floating_size 
= size
; 
3605 void wxAuiManager::OnFloatingPaneClosed(wxWindow
* wnd
, wxCloseEvent
& evt
) 
3607     // try to find the pane 
3608     wxAuiPaneInfo
& pane 
= GetPane(wnd
); 
3609     wxASSERT_MSG(pane
.IsOk(), wxT("Pane window not found")); 
3612     // fire pane close event 
3613     wxAuiManagerEvent 
e(wxEVT_AUI_PANE_CLOSE
); 
3615     e
.SetCanVeto(evt
.CanVeto()); 
3625         // close the pane, but check that it 
3626         // still exists in our pane array first 
3627         // (the event handler above might have removed it) 
3629         wxAuiPaneInfo
& check 
= GetPane(wnd
); 
3639 void wxAuiManager::OnFloatingPaneActivated(wxWindow
* wnd
) 
3641     if ((GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE
) && GetPane(wnd
).IsOk()) 
3643         SetActivePane(m_panes
, wnd
); 
3648 // OnRender() draws all of the pane captions, sashes, 
3649 // backgrounds, captions, grippers, pane borders and buttons. 
3650 // It renders the entire user interface. 
3652 void wxAuiManager::OnRender(wxAuiManagerEvent
& evt
) 
3654     // if the frame is about to be deleted, don't bother 
3655     if (!m_frame 
|| wxPendingDelete
.Member(m_frame
)) 
3658     wxDC
* dc 
= evt
.GetDC(); 
3664     for (i 
= 0, part_count 
= m_uiparts
.GetCount(); 
3665          i 
< part_count
; ++i
) 
3667         wxAuiDockUIPart
& part 
= m_uiparts
.Item(i
); 
3669         // don't draw hidden pane items or items that aren't windows 
3670         if (part
.sizer_item 
&& ((!part
.sizer_item
->IsWindow() && !part
.sizer_item
->IsSpacer() && !part
.sizer_item
->IsSizer()) || !part
.sizer_item
->IsShown())) 
3675             case wxAuiDockUIPart::typeDockSizer
: 
3676             case wxAuiDockUIPart::typePaneSizer
: 
3677                 m_art
->DrawSash(*dc
, m_frame
, part
.orientation
, part
.rect
); 
3679             case wxAuiDockUIPart::typeBackground
: 
3680                 m_art
->DrawBackground(*dc
, m_frame
, part
.orientation
, part
.rect
); 
3682             case wxAuiDockUIPart::typeCaption
: 
3683                 m_art
->DrawCaption(*dc
, m_frame
, part
.pane
->caption
, part
.rect
, *part
.pane
); 
3685             case wxAuiDockUIPart::typeGripper
: 
3686                 m_art
->DrawGripper(*dc
, m_frame
, part
.rect
, *part
.pane
); 
3688             case wxAuiDockUIPart::typePaneBorder
: 
3689                 m_art
->DrawBorder(*dc
, m_frame
, part
.rect
, *part
.pane
); 
3691             case wxAuiDockUIPart::typePaneButton
: 
3692                 m_art
->DrawPaneButton(*dc
, m_frame
, part
.button
->button_id
, 
3693                         wxAUI_BUTTON_STATE_NORMAL
, part
.rect
, *part
.pane
); 
3700 // Render() fire a render event, which is normally handled by 
3701 // wxAuiManager::OnRender().  This allows the render function to 
3702 // be overridden via the render event.  This can be useful for paintin 
3703 // custom graphics in the main window. Default behavior can be 
3704 // invoked in the overridden function by calling OnRender() 
3706 void wxAuiManager::Render(wxDC
* dc
) 
3708     wxAuiManagerEvent 
e(wxEVT_AUI_RENDER
); 
3714 void wxAuiManager::Repaint(wxDC
* dc
) 
3719         m_frame
->Refresh() ; 
3725     m_frame
->GetClientSize(&w
, &h
); 
3727     // figure out which dc to use; if one 
3728     // has been specified, use it, otherwise 
3730     wxClientDC
* client_dc 
= NULL
; 
3733         client_dc 
= new wxClientDC(m_frame
); 
3737     // if the frame has a toolbar, the client area 
3738     // origin will not be (0,0). 
3739     wxPoint pt 
= m_frame
->GetClientAreaOrigin(); 
3740     if (pt
.x 
!= 0 || pt
.y 
!= 0) 
3741         dc
->SetDeviceOrigin(pt
.x
, pt
.y
); 
3743     // render all the items 
3746     // if we created a client_dc, delete it 
3751 void wxAuiManager::OnPaint(wxPaintEvent
& WXUNUSED(event
)) 
3753     wxPaintDC 
dc(m_frame
); 
3757 void wxAuiManager::OnEraseBackground(wxEraseEvent
& event
) 
3766 void wxAuiManager::OnSize(wxSizeEvent
& event
) 
3774         if (m_frame
->IsKindOf(CLASSINFO(wxMDIParentFrame
))) 
3776             // for MDI parent frames, this event must not 
3777             // be "skipped".  In other words, the parent frame 
3778             // must not be allowed to resize the client window 
3779             // after we are finished processing sizing changes 
3787 void wxAuiManager::OnFindManager(wxAuiManagerEvent
& evt
) 
3789     // get the window we are managing, if none, return NULL 
3790     wxWindow
* window 
= GetManagedWindow(); 
3793         evt
.SetManager(NULL
); 
3797     // if we are managing a child frame, get the 'real' manager 
3798     if (window
->IsKindOf(CLASSINFO(wxAuiFloatingFrame
))) 
3800         wxAuiFloatingFrame
* float_frame 
= static_cast<wxAuiFloatingFrame
*>(window
); 
3801         evt
.SetManager(float_frame
->GetOwnerManager()); 
3805     // return pointer to ourself 
3806     evt
.SetManager(this); 
3809 void wxAuiManager::OnSetCursor(wxSetCursorEvent
& event
) 
3812     wxAuiDockUIPart
* part 
= HitTest(event
.GetX(), event
.GetY()); 
3813     wxCursor cursor 
= wxNullCursor
; 
3817         if (part
->type 
== wxAuiDockUIPart::typeDockSizer 
|| 
3818             part
->type 
== wxAuiDockUIPart::typePaneSizer
) 
3820             // a dock may not be resized if it has a single 
3821             // pane which is not resizable 
3822             if (part
->type 
== wxAuiDockUIPart::typeDockSizer 
&& part
->dock 
&& 
3823                 part
->dock
->panes
.GetCount() == 1 && 
3824                 part
->dock
->panes
.Item(0)->IsFixed()) 
3827             // panes that may not be resized do not get a sizing cursor 
3828             if (part
->pane 
&& part
->pane
->IsFixed()) 
3831             if (part
->orientation 
== wxVERTICAL
) 
3832                 cursor 
= wxCursor(wxCURSOR_SIZEWE
); 
3834                 cursor 
= wxCursor(wxCURSOR_SIZENS
); 
3836         else if (part
->type 
== wxAuiDockUIPart::typeGripper
) 
3838             cursor 
= wxCursor(wxCURSOR_SIZING
); 
3842     event
.SetCursor(cursor
); 
3847 void wxAuiManager::UpdateButtonOnScreen(wxAuiDockUIPart
* button_ui_part
, 
3848                                         const wxMouseEvent
& event
) 
3850     wxAuiDockUIPart
* hit_test 
= HitTest(event
.GetX(), event
.GetY()); 
3851     if (!hit_test 
|| !button_ui_part
) 
3854     int state 
= wxAUI_BUTTON_STATE_NORMAL
; 
3856     if (hit_test 
== button_ui_part
) 
3858         if (event
.LeftDown()) 
3859             state 
= wxAUI_BUTTON_STATE_PRESSED
; 
3861             state 
= wxAUI_BUTTON_STATE_HOVER
; 
3865         if (event
.LeftDown()) 
3866             state 
= wxAUI_BUTTON_STATE_HOVER
; 
3869     // now repaint the button with hover state 
3870     wxClientDC 
cdc(m_frame
); 
3872     // if the frame has a toolbar, the client area 
3873     // origin will not be (0,0). 
3874     wxPoint pt 
= m_frame
->GetClientAreaOrigin(); 
3875     if (pt
.x 
!= 0 || pt
.y 
!= 0) 
3876         cdc
.SetDeviceOrigin(pt
.x
, pt
.y
); 
3880         m_art
->DrawPaneButton(cdc
, m_frame
, 
3881                   button_ui_part
->button
->button_id
, 
3883                   button_ui_part
->rect
, 
3888 void wxAuiManager::OnLeftDown(wxMouseEvent
& event
) 
3890     wxAuiDockUIPart
* part 
= HitTest(event
.GetX(), event
.GetY()); 
3893         if (part
->type 
== wxAuiDockUIPart::typeDockSizer 
|| 
3894             part
->type 
== wxAuiDockUIPart::typePaneSizer
) 
3896             // Removing this restriction so that a centre pane can be resized 
3897             //if (part->dock && part->dock->dock_direction == wxAUI_DOCK_CENTER) 
3900             // a dock may not be resized if it has a single 
3901             // pane which is not resizable 
3902             if (part
->type 
== wxAuiDockUIPart::typeDockSizer 
&& part
->dock 
&& 
3903                 part
->dock
->panes
.GetCount() == 1 && 
3904                 part
->dock
->panes
.Item(0)->IsFixed()) 
3907             // panes that may not be resized should be ignored here 
3908             if (part
->pane 
&& part
->pane
->IsFixed()) 
3911             m_action 
= actionResize
; 
3912             m_action_part 
= part
; 
3913             m_action_hintrect 
= wxRect(); 
3914             m_action_start 
= wxPoint(event
.m_x
, event
.m_y
); 
3915             m_action_offset 
= wxPoint(event
.m_x 
- part
->rect
.x
, 
3916                                       event
.m_y 
- part
->rect
.y
); 
3917             m_frame
->CaptureMouse(); 
3919         else if (part
->type 
== wxAuiDockUIPart::typePaneButton
) 
3921             m_action 
= actionClickButton
; 
3922             m_action_part 
= part
; 
3923             m_action_start 
= wxPoint(event
.m_x
, event
.m_y
); 
3924             m_frame
->CaptureMouse(); 
3926             UpdateButtonOnScreen(part
, event
); 
3928         else if (part
->type 
== wxAuiDockUIPart::typeCaption 
|| 
3929                   part
->type 
== wxAuiDockUIPart::typeGripper
) 
3931             // if we are managing a wxAuiFloatingFrame window, then 
3932             // we are an embedded wxAuiManager inside the wxAuiFloatingFrame. 
3933             // We want to initiate a toolbar drag in our owner manager 
3934             wxWindow
* managed_wnd 
= GetManagedWindow(); 
3937                 part
->pane
->window 
&& 
3939                 managed_wnd
->IsKindOf(CLASSINFO(wxAuiFloatingFrame
))) 
3941                 wxAuiFloatingFrame
* floating_frame 
= (wxAuiFloatingFrame
*)managed_wnd
; 
3942                 wxAuiManager
* owner_mgr 
= floating_frame
->GetOwnerManager(); 
3943                 owner_mgr
->StartPaneDrag(part
->pane
->window
, 
3944                                              wxPoint(event
.m_x 
- part
->rect
.x
, 
3945                                                      event
.m_y 
- part
->rect
.y
)); 
3951             if (GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE
) 
3953                 // set the caption as active 
3954                 SetActivePane(m_panes
, part
->pane
->window
); 
3958             if (part
->dock 
&& part
->dock
->dock_direction 
== wxAUI_DOCK_CENTER
) 
3961             m_action 
= actionClickCaption
; 
3962             m_action_part 
= part
; 
3963             m_action_start 
= wxPoint(event
.m_x
, event
.m_y
); 
3964             m_action_offset 
= wxPoint(event
.m_x 
- part
->rect
.x
, 
3965                                       event
.m_y 
- part
->rect
.y
); 
3966             m_frame
->CaptureMouse(); 
3986 void wxAuiManager::OnLeftUp(wxMouseEvent
& event
) 
3988     if (m_action 
== actionResize
) 
3990         m_frame
->ReleaseMouse(); 
3992         // get rid of the hint rectangle 
3994         DrawResizeHint(dc
, m_action_hintrect
); 
3996         // resize the dock or the pane 
3997         if (m_action_part 
&& m_action_part
->type
==wxAuiDockUIPart::typeDockSizer
) 
3999             wxRect
& rect 
= m_action_part
->dock
->rect
; 
4001             wxPoint 
new_pos(event
.m_x 
- m_action_offset
.x
, 
4002                             event
.m_y 
- m_action_offset
.y
); 
4004             switch (m_action_part
->dock
->dock_direction
) 
4006                 case wxAUI_DOCK_LEFT
: 
4007                     m_action_part
->dock
->size 
= new_pos
.x 
- rect
.x
; 
4009                 case wxAUI_DOCK_TOP
: 
4010                     m_action_part
->dock
->size 
= new_pos
.y 
- rect
.y
; 
4012                 case wxAUI_DOCK_RIGHT
: 
4013                     m_action_part
->dock
->size 
= rect
.x 
+ rect
.width 
- 
4014                                   new_pos
.x 
- m_action_part
->rect
.GetWidth(); 
4016                 case wxAUI_DOCK_BOTTOM
: 
4017                     m_action_part
->dock
->size 
= rect
.y 
+ rect
.height 
- 
4018                                   new_pos
.y 
- m_action_part
->rect
.GetHeight(); 
4025         else if (m_action_part 
&& 
4026                  m_action_part
->type 
== wxAuiDockUIPart::typePaneSizer
) 
4028             wxAuiDockInfo
& dock 
= *m_action_part
->dock
; 
4029             wxAuiPaneInfo
& pane 
= *m_action_part
->pane
; 
4031             int total_proportion 
= 0; 
4032             int dock_pixels 
= 0; 
4033             int new_pixsize 
= 0; 
4035             int caption_size 
= m_art
->GetMetric(wxAUI_DOCKART_CAPTION_SIZE
); 
4036             int pane_border_size 
= m_art
->GetMetric(wxAUI_DOCKART_PANE_BORDER_SIZE
); 
4037             int sash_size 
= m_art
->GetMetric(wxAUI_DOCKART_SASH_SIZE
); 
4039             wxPoint 
new_pos(event
.m_x 
- m_action_offset
.x
, 
4040                             event
.m_y 
- m_action_offset
.y
); 
4042             // determine the pane rectangle by getting the pane part 
4043             wxAuiDockUIPart
* pane_part 
= GetPanePart(pane
.window
); 
4044             wxASSERT_MSG(pane_part
, 
4045                        wxT("Pane border part not found -- shouldn't happen")); 
4047             // determine the new pixel size that the user wants; 
4048             // this will help us recalculate the pane's proportion 
4049             if (dock
.IsHorizontal()) 
4050                 new_pixsize 
= new_pos
.x 
- pane_part
->rect
.x
; 
4052                 new_pixsize 
= new_pos
.y 
- pane_part
->rect
.y
; 
4054             // determine the size of the dock, based on orientation 
4055             if (dock
.IsHorizontal()) 
4056                 dock_pixels 
= dock
.rect
.GetWidth(); 
4058                 dock_pixels 
= dock
.rect
.GetHeight(); 
4060             // determine the total proportion of all resizable panes, 
4061             // and the total size of the dock minus the size of all 
4063             int i
, dock_pane_count 
= dock
.panes
.GetCount(); 
4064             int pane_position 
= -1; 
4065             for (i 
= 0; i 
< dock_pane_count
; ++i
) 
4067                 wxAuiPaneInfo
& p 
= *dock
.panes
.Item(i
); 
4068                 if (p
.window 
== pane
.window
) 
4071                 // while we're at it, subtract the pane sash 
4072                 // width from the dock width, because this would 
4073                 // skew our proportion calculations 
4075                     dock_pixels 
-= sash_size
; 
4077                 // also, the whole size (including decorations) of 
4078                 // all fixed panes must also be subtracted, because they 
4079                 // are not part of the proportion calculation 
4082                     if (dock
.IsHorizontal()) 
4083                         dock_pixels 
-= p
.best_size
.x
; 
4085                         dock_pixels 
-= p
.best_size
.y
; 
4089                     total_proportion 
+= p
.dock_proportion
; 
4093             // find a pane in our dock to 'steal' space from or to 'give' 
4094             // space to -- this is essentially what is done when a pane is 
4095             // resized; the pane should usually be the first non-fixed pane 
4096             // to the right of the action pane 
4097             int borrow_pane 
= -1; 
4098             for (i 
= pane_position
+1; i 
< dock_pane_count
; ++i
) 
4100                 wxAuiPaneInfo
& p 
= *dock
.panes
.Item(i
); 
4109             // demand that the pane being resized is found in this dock 
4110             // (this assert really never should be raised) 
4111             wxASSERT_MSG(pane_position 
!= -1, wxT("Pane not found in dock")); 
4113             // prevent division by zero 
4114             if (dock_pixels 
== 0 || total_proportion 
== 0 || borrow_pane 
== -1) 
4116                 m_action 
= actionNone
; 
4120             // calculate the new proportion of the pane 
4121             int new_proportion 
= (new_pixsize
*total_proportion
)/dock_pixels
; 
4123             // default minimum size 
4126             // check against the pane's minimum size, if specified. please note 
4127             // that this is not enough to ensure that the minimum size will 
4128             // not be violated, because the whole frame might later be shrunk, 
4129             // causing the size of the pane to violate it's minimum size 
4130             if (pane
.min_size
.IsFullySpecified()) 
4134                 if (pane
.HasBorder()) 
4135                     min_size 
+= (pane_border_size
*2); 
4137                 // calculate minimum size with decorations (border,caption) 
4138                 if (pane_part
->orientation 
== wxVERTICAL
) 
4140                     min_size 
+= pane
.min_size
.y
; 
4141                     if (pane
.HasCaption()) 
4142                         min_size 
+= caption_size
; 
4146                     min_size 
+= pane
.min_size
.x
; 
4151             // for some reason, an arithmatic error somewhere is causing 
4152             // the proportion calculations to always be off by 1 pixel; 
4153             // for now we will add the 1 pixel on, but we really should 
4154             // determine what's causing this. 
4157             int min_proportion 
= (min_size
*total_proportion
)/dock_pixels
; 
4159             if (new_proportion 
< min_proportion
) 
4160                 new_proportion 
= min_proportion
; 
4164             int prop_diff 
= new_proportion 
- pane
.dock_proportion
; 
4166             // borrow the space from our neighbor pane to the 
4167             // right or bottom (depending on orientation) 
4168             dock
.panes
.Item(borrow_pane
)->dock_proportion 
-= prop_diff
; 
4169             pane
.dock_proportion 
= new_proportion
; 
4176     else if (m_action 
== actionClickButton
) 
4178         m_hover_button 
= NULL
; 
4179         m_frame
->ReleaseMouse(); 
4180         UpdateButtonOnScreen(m_action_part
, event
); 
4182         // make sure we're still over the item that was originally clicked 
4183         if (m_action_part 
== HitTest(event
.GetX(), event
.GetY())) 
4185             // fire button-click event 
4186             wxAuiManagerEvent 
e(wxEVT_AUI_PANE_BUTTON
); 
4188             e
.SetPane(m_action_part
->pane
); 
4189             e
.SetButton(m_action_part
->button
->button_id
); 
4193     else if (m_action 
== actionClickCaption
) 
4195         m_frame
->ReleaseMouse(); 
4197     else if (m_action 
== actionDragFloatingPane
) 
4199         m_frame
->ReleaseMouse(); 
4201     else if (m_action 
== actionDragToolbarPane
) 
4203         m_frame
->ReleaseMouse(); 
4205         wxAuiPaneInfo
& pane 
= GetPane(m_action_window
); 
4206         wxASSERT_MSG(pane
.IsOk(), wxT("Pane window not found")); 
4208         // save the new positions 
4209         wxAuiDockInfoPtrArray docks
; 
4210         FindDocks(m_docks
, pane
.dock_direction
, 
4211                   pane
.dock_layer
, pane
.dock_row
, docks
); 
4212         if (docks
.GetCount() == 1) 
4214             wxAuiDockInfo
& dock 
= *docks
.Item(0); 
4216             wxArrayInt pane_positions
, pane_sizes
; 
4217             GetPanePositionsAndSizes(dock
, pane_positions
, pane_sizes
); 
4219             int i
, dock_pane_count 
= dock
.panes
.GetCount(); 
4220             for (i 
= 0; i 
< dock_pane_count
; ++i
) 
4221                 dock
.panes
.Item(i
)->dock_pos 
= pane_positions
[i
]; 
4224         pane
.state 
&= ~wxAuiPaneInfo::actionPane
; 
4232     m_action 
= actionNone
; 
4233     m_last_mouse_move 
= wxPoint(); // see comment in OnMotion() 
4237 void wxAuiManager::OnMotion(wxMouseEvent
& event
) 
4239     // sometimes when Update() is called from inside this method, 
4240     // a spurious mouse move event is generated; this check will make 
4241     // sure that only real mouse moves will get anywhere in this method; 
4242     // this appears to be a bug somewhere, and I don't know where the 
4243     // mouse move event is being generated.  only verified on MSW 
4245     wxPoint mouse_pos 
= event
.GetPosition(); 
4246     if (m_last_mouse_move 
== mouse_pos
) 
4248     m_last_mouse_move 
= mouse_pos
; 
4251     if (m_action 
== actionResize
) 
4253         wxPoint pos 
= m_action_part
->rect
.GetPosition(); 
4254         if (m_action_part
->orientation 
== wxHORIZONTAL
) 
4255             pos
.y 
= wxMax(0, event
.m_y 
- m_action_offset
.y
); 
4257             pos
.x 
= wxMax(0, event
.m_x 
- m_action_offset
.x
); 
4259         wxRect 
rect(m_frame
->ClientToScreen(pos
), 
4260                     m_action_part
->rect
.GetSize()); 
4263         if (!m_action_hintrect
.IsEmpty()) 
4264             DrawResizeHint(dc
, m_action_hintrect
); 
4265         DrawResizeHint(dc
, rect
); 
4266         m_action_hintrect 
= rect
; 
4268     else if (m_action 
== actionClickCaption
) 
4270         int drag_x_threshold 
= wxSystemSettings::GetMetric(wxSYS_DRAG_X
); 
4271         int drag_y_threshold 
= wxSystemSettings::GetMetric(wxSYS_DRAG_Y
); 
4273         // caption has been clicked.  we need to check if the mouse 
4274         // is now being dragged. if it is, we need to change the 
4275         // mouse action to 'drag' 
4276         if (abs(event
.m_x 
- m_action_start
.x
) > drag_x_threshold 
|| 
4277             abs(event
.m_y 
- m_action_start
.y
) > drag_y_threshold
) 
4279             wxAuiPaneInfo
* pane_info 
= m_action_part
->pane
; 
4281             if (!pane_info
->IsToolbar()) 
4283                 if ((m_flags 
& wxAUI_MGR_ALLOW_FLOATING
) && 
4284                     pane_info
->IsFloatable()) 
4286                     m_action 
= actionDragFloatingPane
; 
4288                     // set initial float position 
4289                     wxPoint pt 
= m_frame
->ClientToScreen(event
.GetPosition()); 
4290                     pane_info
->floating_pos 
= wxPoint(pt
.x 
- m_action_offset
.x
, 
4291                                                       pt
.y 
- m_action_offset
.y
); 
4294                     if (pane_info
->IsMaximized()) 
4295                         RestorePane(*pane_info
); 
4299                     m_action_window 
= pane_info
->frame
; 
4301                     // action offset is used here to make it feel "natural" to the user 
4302                     // to drag a docked pane and suddenly have it become a floating frame. 
4303                     // Sometimes, however, the offset where the user clicked on the docked 
4304                     // caption is bigger than the width of the floating frame itself, so 
4305                     // in that case we need to set the action offset to a sensible value 
4306                     wxSize frame_size 
= m_action_window
->GetSize(); 
4307                     if (frame_size
.x 
<= m_action_offset
.x
) 
4308                         m_action_offset
.x 
= 30; 
4313                 m_action 
= actionDragToolbarPane
; 
4314                 m_action_window 
= pane_info
->window
; 
4318     else if (m_action 
== actionDragFloatingPane
) 
4320         if (m_action_window
) 
4322             wxPoint pt 
= m_frame
->ClientToScreen(event
.GetPosition()); 
4323             m_action_window
->Move(pt
.x 
- m_action_offset
.x
, 
4324                                 pt
.y 
- m_action_offset
.y
); 
4327     else if (m_action 
== actionDragToolbarPane
) 
4329         wxAuiPaneInfo
& pane 
= GetPane(m_action_window
); 
4330         wxASSERT_MSG(pane
.IsOk(), wxT("Pane window not found")); 
4332         pane
.state 
|= wxAuiPaneInfo::actionPane
; 
4334         wxPoint pt 
= event
.GetPosition(); 
4335         DoDrop(m_docks
, m_panes
, pane
, pt
, m_action_offset
); 
4337         // if DoDrop() decided to float the pane, set up 
4338         // the floating pane's initial position 
4339         if (pane
.IsFloating()) 
4341             wxPoint pt 
= m_frame
->ClientToScreen(event
.GetPosition()); 
4342             pane
.floating_pos 
= wxPoint(pt
.x 
- m_action_offset
.x
, 
4343                                         pt
.y 
- m_action_offset
.y
); 
4346         // this will do the actiual move operation; 
4347         // in the case that the pane has been floated, 
4348         // this call will create the floating pane 
4349         // and do the reparenting 
4352         // if the pane has been floated, change the mouse 
4353         // action actionDragFloatingPane so that subsequent 
4354         // EVT_MOTION() events will move the floating pane 
4355         if (pane
.IsFloating()) 
4357             pane
.state 
&= ~wxAuiPaneInfo::actionPane
; 
4358             m_action 
= actionDragFloatingPane
; 
4359             m_action_window 
= pane
.frame
; 
4364         wxAuiDockUIPart
* part 
= HitTest(event
.GetX(), event
.GetY()); 
4365         if (part 
&& part
->type 
== wxAuiDockUIPart::typePaneButton
) 
4367             if (part 
!= m_hover_button
) 
4369                 // make the old button normal 
4372                     UpdateButtonOnScreen(m_hover_button
, event
); 
4376                 // mouse is over a button, so repaint the 
4377                 // button in hover mode 
4378                 UpdateButtonOnScreen(part
, event
); 
4379                 m_hover_button 
= part
; 
4387                 m_hover_button 
= NULL
; 
4398 void wxAuiManager::OnLeaveWindow(wxMouseEvent
& WXUNUSED(event
)) 
4402         m_hover_button 
= NULL
; 
4407 void wxAuiManager::OnChildFocus(wxChildFocusEvent
& event
) 
4409     // when a child pane has it's focus set, we should change the 
4410     // pane's active state to reflect this. (this is only true if 
4411     // active panes are allowed by the owner) 
4412     if (GetFlags() & wxAUI_MGR_ALLOW_ACTIVE_PANE
) 
4414         wxAuiPaneInfo
& pane 
= GetPane(event
.GetWindow()); 
4415         if (pane
.IsOk() && (pane
.state 
& wxAuiPaneInfo::optionActive
) == 0) 
4417             SetActivePane(m_panes
, event
.GetWindow()); 
4426 // OnPaneButton() is an event handler that is called 
4427 // when a pane button has been pressed. 
4428 void wxAuiManager::OnPaneButton(wxAuiManagerEvent
& evt
) 
4430     wxASSERT_MSG(evt
.pane
, wxT("Pane Info passed to wxAuiManager::OnPaneButton must be non-null")); 
4432     wxAuiPaneInfo
& pane 
= *(evt
.pane
); 
4434     if (evt
.button 
== wxAUI_BUTTON_CLOSE
) 
4436         // fire pane close event 
4437         wxAuiManagerEvent 
e(wxEVT_AUI_PANE_CLOSE
); 
4439         e
.SetPane(evt
.pane
); 
4444             // close the pane, but check that it 
4445             // still exists in our pane array first 
4446             // (the event handler above might have removed it) 
4448             wxAuiPaneInfo
& check 
= GetPane(pane
.window
); 
4457     else if (evt
.button 
== wxAUI_BUTTON_MAXIMIZE_RESTORE 
&& !pane
.IsMaximized()) 
4459         // fire pane close event 
4460         wxAuiManagerEvent 
e(wxEVT_AUI_PANE_MAXIMIZE
); 
4462         e
.SetPane(evt
.pane
); 
4471     else if (evt
.button 
== wxAUI_BUTTON_MAXIMIZE_RESTORE 
&& pane
.IsMaximized()) 
4473         // fire pane close event 
4474         wxAuiManagerEvent 
e(wxEVT_AUI_PANE_RESTORE
); 
4476         e
.SetPane(evt
.pane
); 
4485     else if (evt
.button 
== wxAUI_BUTTON_PIN
) 
4487         if ((m_flags 
& wxAUI_MGR_ALLOW_FLOATING
) &&