Main Page | Namespace List | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

dockhost.cpp

Go to the documentation of this file.
00001 
00002 // Name:        wxDockHost.cpp
00003 // Purpose:     wxDockHost implementation.
00004 // Author:      Mark McCormack
00005 // Modified by:
00006 // Created:     23/02/04
00007 // RCS-ID:      $Id: dockhost.cpp,v 1.13 2005/05/12 14:04:47 frm Exp $
00008 // Copyright:   (c) 2004 Mark McCormack
00009 // Licence:     wxWindows license
00011 
00012 #include <wx/dockhost.h>
00013 #include <wx/dockwindow.h>
00014 #include <wx/dockpanel.h>
00015 #include <wx/gdi.h>
00016 #include <wx/exsplitter.h>
00017 
00018 #include <wx/list.h>
00019 #include <wx/listimpl.cpp>
00020 
00021 // ----------------------------------------------------------------------------
00022 // wxDockHost constants & wx-macros
00023 // ----------------------------------------------------------------------------
00024 
00025 IMPLEMENT_CLASS( wxDockHost, wxPanel )
00026 
00027 BEGIN_EVENT_TABLE( wxDockHost, wxPanel )
00028     EVT_SIZE( wxDockHost::OnSize )
00029     EVT_SPLITTER_MOVED( wxDockHost::OnSplitterMoved )
00030     EVT_CALCULATE_LAYOUT( wxDockHost::OnCalculateLayout )
00031 END_EVENT_TABLE()
00032 
00033 WX_DEFINE_LIST( DockWindowList );
00034 WX_DEFINE_LIST( SplitterList );
00035 
00036 // ----------------------------------------------------------------------------
00037 // wxDockHost implementation
00038 // ----------------------------------------------------------------------------
00039 
00040 wxDockHost::~wxDockHost() {
00041     delete pSizingSplitter_;
00042 }
00043 
00044 void wxDockHost::Init() {
00045     dir_ = wxALL;
00046     areaSize_ = wxINITIAL_HOST_SIZE;
00047     panelArea_ = 0;
00048     lockPanelValue_ = false;
00049     internalSizeEvent_ = false;
00050     pLayoutManager_ = NULL;
00051     pos_.x = 0;
00052     pos_.y = 0;
00053     size_.x = 0;
00054     size_.y = 0;
00055     numPanels_ = 0;
00056     numSplitters_ = 0;
00057     splitterFlags_ = 0x0000;
00058     pSizingSplitter_ = NULL;
00059     splitters_.Clear();
00060     dockWindows_.Clear();
00061 }
00062 
00063 bool wxDockHost::Create( wxWindow *parent, wxWindowID id, wxDirection dir, const wxString& name ) {
00064     wxASSERT(parent);
00065     dir_ = dir;
00066     bool r = wxPanel::Create( parent, id, pos_, size_, wxTAB_TRAVERSAL | wxCLIP_CHILDREN, name );
00067 
00068     return r;
00069 }
00070 
00071 void wxDockHost::SetLayoutManager( wxLayoutManager * pLayoutManager ) {
00072     pLayoutManager_ = pLayoutManager;
00073 
00074     // create sizer splitter
00075     wxWindow * win1 = (dir_ == wxLEFT || dir_ == wxTOP) ? this : NULL;
00076     wxWindow * win2 = (dir_ == wxRIGHT || dir_ == wxBOTTOM) ? this : NULL;
00077     wxOrientation orientation = (GetOrientation() == wxHORIZONTAL) ? wxVERTICAL : wxHORIZONTAL;
00078     pSizingSplitter_ = new wxExSplitter( this, orientation, win1, win2, 0x0000 );
00079     SettingsChanged();
00080 }
00081 
00082 wxLayoutManager * wxDockHost::GetLayoutManager() {
00083     return pLayoutManager_;
00084 }
00085 
00086 void wxDockHost::SetAreaSize( int size ) {
00087     areaSize_ = size;
00088 }
00089 
00090 int wxDockHost::GetAreaSize() {
00091     return areaSize_;
00092 }
00093 
00094 DockWindowList & wxDockHost::GetDockWindowList() {
00095     DockWindowList dockWindows;
00096 
00097     wxWindowList & children = GetChildren();
00098     dockWindows_.Clear();
00099     for( int c=0; c<(int)children.GetCount(); c++ ) {
00100         // get child
00101         wxWindowListNode * pChildNode = children.Item( c );
00102         wxASSERT(pChildNode);
00103         wxWindow * pChild = pChildNode->GetData();
00104         wxASSERT(pChild);
00105     
00106         // is it a panel?
00107         wxDockPanel * pPanel = wxDynamicCast( pChild, wxDockPanel );
00108         if( pPanel ) {
00109             // add the panel's window
00110             dockWindows_.Append( pPanel->GetDockWindow() );
00111         }
00112     }
00113 
00114     return dockWindows_;
00115 }
00116 
00117 void wxDockHost::OnSize( wxSizeEvent &event ) {
00118     if( !pLayoutManager_ ) {
00119         // we have not beem given an owner yet, ignore event
00120         return;
00121     }
00122 
00123     wxSize newSize = event.GetSize();
00124     if( !IsEmpty() ) {
00125         // if host is being used then update the host's area value
00126         if( GetOrientation() == wxHORIZONTAL ) {
00127             areaSize_ = newSize.GetHeight();
00128         }
00129         else {
00130             areaSize_ = newSize.GetWidth();
00131         }
00132         
00133         if( !internalSizeEvent_ ) {
00134             pLayoutManager_->UpdateAllHosts( true, this );
00135         }
00136     }
00137     UpdateSize( true );
00138 }
00139 
00140 void wxDockHost::OnSplitterMoved( wxCommandEvent &event ) {
00141     if( event.GetEventObject() != pSizingSplitter_ ) {
00142         // recalc on panel splitter movement
00143         RecalcPanelAreas();
00144     }
00145 }
00146 
00147 void wxDockHost::UpdateSize( bool useProportions ) {
00148     // calculate where we should be
00149 /*
00150     wxRect hp = CalcHostPlacement();
00151     if( pLayoutManager_ ) {
00152         // ask the manager for trim with other hosts
00153         hp = pLayoutManager_->TrimDockArea( this, hp );
00154     }
00155     SetSize( hp );
00156 */
00157     calcPanelPlacement( useProportions );
00158 }
00159 
00160 void wxDockHost::DockPanel( wxDockPanel * pDockPanel, wxHostInfo &hi ) {
00161     if( hi.pPanel == pDockPanel ) {
00162         // we don't need to do anything
00163         return;
00164     }
00165 
00166     // make the panel a child of this host
00167     pDockPanel->Reparent( this );
00168 
00169     wxWindowList & children = GetChildren();
00170 
00171     // if a target panel was specified, move child in relation to where we want it in the children list
00172     if( hi.pPanel ) {
00173         int insertIndex = children.IndexOf( hi.pPanel );
00174         if( insertIndex == wxNOT_FOUND ) {
00175             // panel no longer exists in this host
00176             hi.pPanel = NULL;
00177         }
00178     }
00179 
00180     // delete original node
00181     wxWindowListNode * pNode = children.Find( pDockPanel );
00182     children.DeleteNode( pNode );
00183 
00184     int insertIndex = children.IndexOf( hi.pPanel );
00185     if( insertIndex != wxNOT_FOUND ) {
00186         // inserting panel is found, to the front or back?
00187         if( hi.placement == wxHIP_BACK ) {
00188             insertIndex++;
00189         }
00190         children.Insert( insertIndex, pDockPanel );
00191     }
00192     else {
00193         // panel does not exist, insert at the back
00194         int count = getAssetCount();
00195         if( count > 0 ) {
00196             wxWindowListNode * pChildNode = children.Item( count-1 );
00197             wxASSERT(pChildNode);
00198             hi.pPanel = wxDynamicCast( pChildNode->GetData(), wxDockPanel );
00199             hi.placement = wxHIP_BACK;
00200         }
00201         children.Append( pDockPanel );
00202     }
00203 
00204     RecalcPanelAreas();
00205 
00206     // Removed this block of code so that the values calc'd in RecalcPanelAreas() is not overridden
00207 /*    if( hi.pPanel ) {
00208         // split area with target dock panel
00209         int newArea = (hi.pPanel->GetArea() - wxSPLITTER_SIZE) / 2;
00210         hi.pPanel->SetArea( newArea );
00211         pDockPanel->SetArea( newArea );
00212     }
00213     else {
00214         // dock panel has all the available area
00215         pDockPanel->SetArea( panelArea_ );
00216     } */
00217 
00218     pDockPanel->SetDockedHost( this );
00219 }
00220 
00221 void wxDockHost::UndockPanel( wxDockPanel * pDockPanel ) {
00222     // see if we have any information about how we docked
00223     wxWindowList & children = GetChildren();
00224 
00225     // find node
00226     wxWindowListNode * pNode = children.Find( pDockPanel );
00227     assert(pNode);
00228     wxDockPanel * pGivePanel = NULL;
00229 
00230     // distribute free area
00231     if( getAssetCount() > 1 ) {
00232         int lastIndex = children.GetCount()-1;
00233         wxWindowListNode * pLastNode = children.Item( lastIndex );
00234         wxASSERT(pLastNode);
00235         if( pNode == pLastNode ) {
00236             // node is the last node, give to prev
00237             do {
00238                 pNode = children.Item( --lastIndex );
00239                 pGivePanel = wxDynamicCast( pNode->GetData(), wxDockPanel );
00240             } while( !pGivePanel );
00241         }
00242         else {
00243             // give to next
00244             int currentIndex = children.IndexOf( pDockPanel );
00245             do {
00246                 pNode = children.Item( ++currentIndex );
00247                 pGivePanel = wxDynamicCast( pNode->GetData(), wxDockPanel );
00248             } while( !pGivePanel );
00249         }
00250     }
00251 
00252     // give the area back
00253     if( pGivePanel ) {
00254         int newArea = pDockPanel->GetArea() + pGivePanel->GetArea() + wxSPLITTER_SIZE;
00255         pGivePanel->SetArea( newArea );
00256     }
00257 
00258     // remove the panel from this host
00259     wxDockWindowBase * pDockWindow = pDockPanel->GetDockWindow();
00260     pDockPanel->Reparent( pDockWindow );
00261 
00262     pDockPanel->SetDockedHost( NULL );
00263 }
00264 
00265 wxRect wxDockHost::GetScreenArea() {
00266     // return the screen area for this host
00267     wxRect hp = CalcHostPlacement( true );
00268     if( pLayoutManager_ ) {
00269         hp = pLayoutManager_->TrimDockArea( this, hp );
00270     }
00271 
00272     return pLayoutManager_->RectToScreen( hp );
00273 }
00274 
00275 wxRect wxDockHost::GetScreenArea( wxHostInfo &hi ) {
00276     // return the screen area for the info
00277     if( !hi.pPanel ) {
00278         return GetScreenArea();
00279     }
00280     else {
00281         return hi.pPanel->GetScreenArea( hi );
00282     }
00283 }
00284 
00285 wxRect wxDockHost::GetClientArea() {
00286     // return the client area for this host
00287     return CalcHostPlacement();
00288 }
00289 
00290  wxOrientation wxDockHost::GetOrientation() {
00291     switch( dir_ ) {
00292         case wxLEFT:
00293         case wxRIGHT:
00294             return wxVERTICAL;
00295         break;
00296         
00297         case wxTOP:
00298         case wxBOTTOM:
00299             return wxHORIZONTAL;
00300         break;
00301         case wxALL:
00302             wxASSERT_MSG( false, wxT("wxALL is not valid") );
00303         break;
00304     }
00305     // failed
00306     return wxHORIZONTAL;
00307 }
00308 wxDirection wxDockHost::GetDirection() {
00309     return dir_;
00310 }
00311  
00312 wxRect wxDockHost::CalcHostPlacement( bool hitTest ) {
00313     int area = areaSize_;
00314     if( IsEmpty() ) {
00315         // host is empty
00316         if( !hitTest ) {
00317             // no testing - therefore, no size
00318             area = 0;
00319         }
00320     }
00321 
00322     // lets work out where we would like to go
00323     wxRect pcr = pLayoutManager_->GetDockArea();
00324     switch( dir_ ) {
00325         case wxLEFT:
00326             pos_.x = pcr.x;
00327             pos_.y = pcr.y;
00328             size_.x = area;
00329             size_.y = pcr.height;
00330         break;
00331         case wxTOP:
00332             pos_.x = pcr.x;
00333             pos_.y = pcr.y;
00334             size_.x = pcr.width;
00335             size_.y = area;
00336         break;
00337         case wxBOTTOM:
00338             pos_.x = pcr.x;
00339             pos_.y = pcr.GetBottom() - area;
00340             size_.x = pcr.width;
00341             size_.y = area;
00342         break;
00343         case wxRIGHT:
00344             pos_.x = pcr.GetRight() - area;
00345             pos_.y = pcr.y;
00346             size_.x = area;
00347             size_.y = pcr.height;
00348         break;        
00349         case wxALL:
00350             // n/a
00351         break;
00352     }
00353     wxRect t( pos_, size_ );
00354     return t;
00355 }
00356 
00357 bool wxDockHost::IsEmpty() {
00358     return getAssetCount() == 0;
00359 }
00360 
00361 bool wxDockHost::TestForPanel( int sx, int sy, wxHostInfo &hi ) {
00362     if( IsEmpty() ) {
00363         // host is empty
00364         wxRect hRect = GetScreenArea();
00365         if( hRect.Inside( sx, sy ) ) {
00366             hi = this;
00367             return true;
00368         }
00369     }
00370     
00371     wxWindowList & children = GetChildren();
00372     for( int c=0; c<(int)children.GetCount(); c++ ) {
00373         // get child
00374         wxWindowListNode * pChildNode = children.Item( c );
00375         wxASSERT(pChildNode);
00376         wxWindow * pChild = pChildNode->GetData();
00377         wxASSERT(pChild);
00378     
00379         // is it a panel?
00380         wxDockPanel * pPanel = wxDynamicCast( pChild, wxDockPanel );
00381         if( pPanel ) {
00382             wxRect localRect = pPanel->GetRect();
00383             wxRect screenRect = RectToScreen( localRect );
00384             if( screenRect.Inside( sx, sy ) ) {
00385                 // hit-test success on panel
00386                 hi = this;
00387                 hi.pPanel = pPanel;
00388                 hi.placement = pPanel->TestForPlacement( sx, sy );
00389                 return true;
00390             }
00391         }
00392     }
00393     return false;
00394 }
00395 
00396 wxRect wxDockHost::RectToScreen( wxRect &rect ) {
00397     // convert an child rect to screen rect
00398     wxRect tRect( rect );
00399     wxPoint pos = ClientToScreen( tRect.GetPosition() );
00400     tRect.SetPosition( pos );
00401     return tRect;
00402 }
00403 
00404 void wxDockHost::RecalcPanelAreas() {
00405     // get the client window 
00406     wxRect cr = GetClientRect();
00407 
00408     // set the available panel area
00409     int hostArea = GetOrientation() == wxHORIZONTAL ? cr.width : cr.height;
00410 
00411     int splittersArea = (numSplitters_ * wxSPLITTER_SIZE);
00412     if( !lockPanelValue_ ) {
00413         panelArea_ = (hostArea - splittersArea);
00414     }
00415  
00416     wxWindowList & children = GetChildren();
00417     int childCount = children.GetCount();
00418 
00419     // This calculates an equal area for each child panel
00420     int equalArea = panelArea_ / ((childCount + 1) / 2);
00421 
00422     for( int c=0; c<childCount; c++ ) {
00423         // get child
00424         wxWindowListNode * pChildNode = children.Item( c );
00425         wxASSERT(pChildNode);
00426         wxWindow * pChild = pChildNode->GetData();
00427         wxASSERT(pChild);
00428 
00429         // what is it?
00430         wxDockPanel * pPanel = wxDynamicCast( pChild, wxDockPanel );
00431         if( pPanel ) {
00432             // set the taken panel area
00433             pPanel->SetArea( equalArea ); 
00434         }
00435     }
00436 }
00437 
00438 void wxDockHost::OnCalculateLayout( wxCalculateLayoutEvent &event ) {
00439     // check for a 'query only' event
00440     bool queryMode = false;
00441     if( (event.GetFlags() & wxLAYOUT_QUERY) != 0 ) {
00442         queryMode = true;
00443     }
00444 
00445     wxRect areaRect = event.GetRect();
00446 
00447     // if we are the first host then save the area as the 'docking area'
00448     if( pLayoutManager_->IsPrimaryDockHost( this ) ) {
00449         pLayoutManager_->SetDockArea( areaRect );
00450     }
00451 
00452     if( IsEmpty() ) {
00453         // we have no effect when we are empty
00454         SetSize( 0,0,0,0 );
00455         return;
00456     }
00457     
00458     internalSizeEvent_ = true;
00459 
00460     // chew off a bit of area for ourselves from the layout area
00461     switch( GetDirection() ) {
00462         case wxLEFT:
00463             if( !queryMode ) SetSize( areaRect.GetX(), areaRect.GetY(), areaSize_, areaRect.GetHeight() );
00464             areaRect.SetX( areaRect.GetX() + areaSize_ );
00465             areaRect.SetWidth( areaRect.GetWidth() - areaSize_ );
00466             break;
00467         case wxTOP:
00468             if( !queryMode ) SetSize( areaRect.GetX(), areaRect.GetY(), areaRect.GetWidth(), areaSize_ );
00469             areaRect.SetY( areaRect.GetY() + areaSize_ );
00470             areaRect.SetHeight( areaRect.GetHeight() - areaSize_ );
00471             break;
00472         case wxBOTTOM:
00473             if( !queryMode ) SetSize( areaRect.GetX(), areaRect.GetY() + (areaRect.GetHeight() - areaSize_), areaRect.GetWidth(), areaSize_ );
00474             areaRect.SetHeight( areaRect.GetHeight() - areaSize_ );
00475             break;
00476         case wxRIGHT:
00477             if( !queryMode ) SetSize( areaRect.GetX() + (areaRect.GetWidth() - areaSize_), areaRect.GetY(), areaSize_, areaRect.GetHeight() );
00478             areaRect.SetWidth( areaRect.GetWidth() - areaSize_ );
00479             break;
00480         break;
00481         case wxALL:
00482             // n/a
00483         break;
00484     }
00485     event.SetRect( areaRect );
00486 
00487     internalSizeEvent_ = false;
00488 }
00489 
00490 void wxDockHost::SettingsChanged() {
00491     unsigned int dwFlags = pLayoutManager_->GetFlags();
00492     bool liveUpdate = (dwFlags & wxDWF_LIVE_UPDATE) == wxDWF_LIVE_UPDATE;
00493     bool splitterBorders = (dwFlags & wxDWF_SPLITTER_BORDERS) == wxDWF_SPLITTER_BORDERS;
00494 
00495     unsigned int flags = liveUpdate ? wxESF_LIVE_UPDATE : 0;
00496     flags |= splitterBorders ? wxESF_DRAW_GRIPPER : 0;
00497     
00498     // inform our splitters
00499     for( unsigned int i=0; i<splitters_.GetCount(); ++i ) {
00500         wxExSplitter * pSplitter = splitters_[i];
00501         pSplitter->SetFlags( flags );
00502     }
00503     pSizingSplitter_->SetFlags( flags );
00504     splitterFlags_ = flags;
00505 }
00506 
00507 void wxDockHost::calcPanelPlacement( bool useProportions ) {
00508     updateSplitters();
00509 
00510     wxWindowList & children = GetChildren();
00511     int childCount = children.GetCount();
00512     if( IsEmpty() ) {
00513         return;
00514     }
00515    
00516     // get the client window 
00517     wxRect cr = GetClientRect();
00518     
00519     int areaRemaining = GetOrientation() == wxHORIZONTAL ? cr.width : cr.height;
00520     int splittersArea = (numSplitters_ * wxSPLITTER_SIZE);
00521     int panelArea = (areaRemaining - splittersArea);
00522     int panelAllowance = panelArea;
00523     int areaPos = 0;
00524     int panelCount = 0;
00525     for( int c=0; c<childCount; c++ ) {
00526         // get child
00527         wxWindowListNode * pChildNode = children.Item( c );
00528         wxASSERT(pChildNode);
00529         wxWindow * pChild = pChildNode->GetData();
00530         wxASSERT(pChild);
00531 
00532         if( pChild == pSizingSplitter_ ) {
00533             // ignore host's own size splitter
00534             continue;
00535         }
00536 
00537         // what is it?
00538         wxDockPanel * pPanel = wxDynamicCast( pChild, wxDockPanel );
00539 
00540         int childChunk = 0;
00541         if( !pPanel ) {
00542             // is a splitter
00543             childChunk = wxSPLITTER_SIZE;
00544         }
00545         else {
00546             panelCount++;
00547 
00548             // give the panel it's required proportion of the available size
00549             if( panelCount < numPanels_ ) {
00550                 if( useProportions ) {
00551                     // use proportions
00552                     float proportion = (float)pPanel->GetArea() / panelArea_;
00553                     childChunk = (int)((float)proportion * panelArea);
00554                 }
00555                 else {
00556                     // use absolutes
00557                     childChunk = pPanel->GetArea();
00558                 }
00559                 panelAllowance -= childChunk;
00560             }
00561             else {
00562                 // last chunk gets whatever is left over
00563                 childChunk = panelAllowance;
00564                 panelAllowance = 0;
00565             }
00566         }
00567 
00568         // adjust size
00569         if( GetOrientation() == wxHORIZONTAL ) {
00570             int top = (dir_ == wxTOP) ? 0 : wxSPLITTER_SIZE;
00571             int height = cr.height - wxSPLITTER_SIZE;
00572             pChild->SetSize( areaPos, top, childChunk, height );
00573         }
00574         else {
00575             int left = (dir_ == wxLEFT) ? 0 : wxSPLITTER_SIZE;
00576             int width = cr.width - wxSPLITTER_SIZE;
00577             pChild->SetSize( left, areaPos, width, childChunk );
00578         }
00579         areaPos += childChunk + 1;  // XXX: not sure if we should have to do this extra increment?
00580     }
00581 
00582     assert(pSizingSplitter_);
00583 
00584     // adjust size splitter
00585     if( GetOrientation() == wxHORIZONTAL ) {
00586         int areaHeight = cr.height - wxSPLITTER_SIZE;
00587         int splitterTop = (dir_ == wxTOP) ? areaHeight : 0;
00588         pSizingSplitter_->SetSize( 0, splitterTop, cr.width, wxSPLITTER_SIZE );
00589     }
00590     else {
00591         int areaWidth = cr.width - wxSPLITTER_SIZE;
00592         int splitterLeft = (dir_ == wxLEFT) ? areaWidth : 0;
00593         pSizingSplitter_->SetSize( splitterLeft, 0, wxSPLITTER_SIZE, cr.height );
00594     }
00595 
00596     if( lockPanelValue_ ) {
00597         // recalc on load
00598         RecalcPanelAreas();
00599     }
00600  }
00601 
00602 int wxDockHost::getAssetCount() {
00603     wxWindowList & children = GetChildren();
00604     int childCount = children.GetCount();
00605 
00606     // removes 1 for the host's own splitter
00607     return childCount-1;      
00608 }
00609 
00610 void wxDockHost::updateSplitters() {
00611 
00612     // adds/removes splitters dynamically as required
00613     wxWindowList & children = GetChildren();
00614     int childCount = children.GetCount();
00615 
00616     eChildType lastChildType = CT_NONE;
00617     wxWindow * pLastChild = NULL;
00618     numPanels_ = 0;
00619     numSplitters_ = 0;
00620     wxWindowList newChildList;
00621     SplitterList toDeleteSplitters;
00622     splitters_.Clear();
00623     
00624     int c;
00625     for( c=0; c<childCount; c++ ) {
00626         // get child
00627         wxWindowListNode * pChildNode = children.Item( c );
00628         wxASSERT(pChildNode);
00629         wxWindow * pChild = pChildNode->GetData();
00630         wxASSERT(pChild);
00631 
00632         if( pChild == pSizingSplitter_ ) {
00633             newChildList.Append( pSizingSplitter_ );
00634 
00635             // ignore host's own size splitter
00636             continue;
00637         }
00638 
00639         // what is it?
00640         wxDockPanel * pPanel = wxDynamicCast( pChild, wxDockPanel );
00641         if( pPanel ) {
00642             if( lastChildType == CT_PANEL ) {
00643                 // we need to add a splitter
00644                 wxASSERT(pLastChild);
00645 
00646                 wxExSplitter * pSplitter = new wxExSplitter( this, GetOrientation(), pLastChild, pPanel, splitterFlags_ );
00647                 
00648                 newChildList.Append( pSplitter );
00649                 numSplitters_++;
00650                 splitters_.Append( pSplitter );
00651             }
00652             // add original panel
00653             newChildList.Append( pPanel );
00654             numPanels_++;
00655 
00656             // save lasts
00657             lastChildType = CT_PANEL;
00658             pLastChild = (wxWindow *)pPanel;
00659         }
00660         else {
00661             if( lastChildType == CT_SPLITTER || c == 1 || c == (childCount-1) ) {
00662                 // we need to remove a splitter
00663                 wxExSplitter * pPanelSplitter = wxDynamicCast( pChildNode->GetData(), wxExSplitter );
00664                 toDeleteSplitters.Append( pPanelSplitter );
00665             }
00666             else {
00667                 // add original splitter
00668                 pLastChild = wxDynamicCast( pChildNode->GetData(), wxExSplitter );
00669                 newChildList.Append( pLastChild );
00670                 numSplitters_++;
00671                 splitters_.Append( (wxExSplitter *)pLastChild );
00672             }
00673             // save lasts
00674             lastChildType = CT_SPLITTER;
00675         }
00676     }
00677 
00678     // delete unrequired splitters
00679     for ( SplitterList::Node *node = toDeleteSplitters.GetFirst(); node; node = node->GetNext() ) {
00680         delete node->GetData();
00681     }
00682 
00683     // update window list
00684     children = newChildList;
00685     
00686     // make sure splitters are connected to the correct panels
00687     int newChildCount = children.GetCount();
00688     for( c=0; c<newChildCount; c++ ) {
00689         // get child
00690         wxWindowListNode * pChildNode = children.Item( c );
00691         wxASSERT(pChildNode);
00692 
00693         wxExSplitter * pPanelSplitter = wxDynamicCast( pChildNode->GetData(), wxExSplitter );
00694         if( pPanelSplitter == pSizingSplitter_ ) {
00695             // ignore host's own size splitter
00696             continue;
00697         }
00698 
00699         if( pPanelSplitter ) {
00700             // get panels to either side of the splitter
00701             wxASSERT(c>1);
00702             wxASSERT(c<(newChildCount-1));
00703             wxDockPanel * pFrontPanel = wxDynamicCast( children.Item( c-1 )->GetData(), wxDockPanel );
00704             wxASSERT(pFrontPanel);
00705             wxDockPanel * pBackPanel = wxDynamicCast( children.Item( c+1 )->GetData(), wxDockPanel );
00706             wxASSERT(pBackPanel);
00707             pPanelSplitter->SetWindows( pFrontPanel, pBackPanel );
00708         }
00709     }
00710 }

Generated on Sat May 14 14:54:39 2005 for wxDockIt by  doxygen 1.4.2