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

dockwindow.cpp

Go to the documentation of this file.
00001 
00002 // Name:        wxDockWindow.cpp
00003 // Purpose:     wxDockWindowBase implementation.
00004 // Author:      Mark McCormack
00005 // Modified by:
00006 // Created:     23/02/04
00007 // RCS-ID:      $Id: dockwindow.cpp,v 1.10 2005/05/12 14:04:48 frm Exp $
00008 // Copyright:   (c) 2004 Mark McCormack
00009 // Licence:     wxWindows license
00011 
00012 #include <wx/dockwindow.h>
00013 #include <wx/dockpanel.h>
00014 #include <wx/dockhost.h>
00015 #include <wx/gdi.h>
00016 
00017 #include <wx/dcscreen.h>
00018 #include <wx/sizer.h>
00019 #include <wx/tooltip.h>
00020 
00021 // ----------------------------------------------------------------------------
00022 // wxDockWindowBase constants & wx-macros
00023 // ----------------------------------------------------------------------------
00024 
00025 const long dockWindowStyle = (wxDEFAULT_FRAME_STYLE /*| wxFRAME_TOOL_WINDOW*/ | wxFRAME_FLOAT_ON_PARENT);
00026 
00027 IMPLEMENT_CLASS( wxDockWindowBase, wxMiniFrame )
00028 
00029 BEGIN_EVENT_TABLE( wxDockWindowBase, wxMiniFrame )
00030     EVT_MOTION( wxDockWindowBase::OnMouseMove )
00031     EVT_CLOSE( wxDockWindowBase::OnClose )  
00032 END_EVENT_TABLE()
00033 
00034 // ----------------------------------------------------------------------------
00035 // wxDockWindowBase implementation
00036 // ----------------------------------------------------------------------------
00037 
00038 void wxDockWindowBase::Init() {
00039     dragging_ = false;
00040     haveMoved_ = false;
00041     startRect_.Reset();
00042     prevRect_.Reset();
00043     dragRect_.Reset();
00044     startPoint_.x = 0;
00045     startPoint_.y = 0;
00046     newHost_.Reset();
00047     prevHost_.Reset();
00048     pLayoutManager_ = NULL;
00049     pClientPanel_ = NULL;
00050     docked_ = false;
00051     flags_= 0x0000;
00052     disableShowOverride_ = false;
00053 }
00054 
00055 bool wxDockWindowBase::Create( wxWindow *parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, const wxString& name, unsigned int flags ) {
00056     wxASSERT(parent);
00057     bool r = wxMiniFrame::Create( parent, id, title, pos, size, dockWindowStyle, name );
00058     flags_ = flags;
00059     title_ = title;
00060     visible_ = false;
00061 
00062 #ifdef __WXGTK__
00063     // we will draw our own titlebar & close widget
00064     m_miniTitle = 0;
00065 #endif
00066     createClient();
00067 
00068     return r;
00069 }
00070 
00071 void wxDockWindowBase::SetDockingManager( wxLayoutManager * pLayoutManager ) {
00072     pLayoutManager_ = pLayoutManager;
00073 }
00074 
00075 wxLayoutManager * wxDockWindowBase::GetLayoutManager() {
00076     return pLayoutManager_;
00077 }
00078 
00079 void wxDockWindowBase::Appear() {
00080     if( IsDocked() ) {
00081         // ignore if we are already docked
00082         if( pClientPanel_->IsDocked() ) {
00083             return;
00084         }
00085         
00086         // re-dock the panel from the owner window back onto the host
00087         if( !applyLastDock( true ) ) {
00088             // could not re-dock, so just show the window floating
00089             ActualShow();
00090         }
00091     }
00092     else {
00093         ActualShow();
00094     }
00095     visible_ = true;
00096 }
00097 
00098 void wxDockWindowBase::Remove() {
00099     if( IsDocked() ) {
00100        // ignore if we are already undocked
00101         if( !pClientPanel_->IsDocked() ) {
00102             return;
00103         }
00104 
00105         wxLayoutManager * pLayoutManager = GetLayoutManager();
00106         wxASSERT(pLayoutManager);
00107 
00108         // undock the panel back onto the owner window
00109         pLayoutManager->UndockWindow( this, true );
00110     }
00111     else {
00112         ActualShow( false );
00113     }
00114     visible_ = false;
00115 }
00116 
00117 void wxDockWindowBase::AutoFitSingleChild() {
00118     // tell the dock panel to auto fit
00119     wxASSERT(pClientPanel_);
00120     pClientPanel_->AutoFitSingleChild();
00121 }
00122 
00123 void wxDockWindowBase::SetClient( wxWindow * pClient, bool autoPane ) {
00124     // replace our panel's client
00125     pClientPanel_->SetClient( pClient, autoPane );
00126 }
00127 
00128 wxWindow * wxDockWindowBase::GetClient() {
00129     // return the actual client
00130     return pClientPanel_->GetClient();
00131 }
00132 
00133 wxWindow * wxDockWindowBase::RemoveClient( wxWindow * pNewParent ) {
00134     wxWindow * pClient = GetClient();
00135 
00136     // replace our panel's client with the stock client
00137     pClientPanel_->SetClient( NULL );
00138 
00139     // reparent old client?
00140     if( pClient && pNewParent ) {
00141         pClient->Reparent( pNewParent );
00142     }
00143 
00144     return pClient;
00145 }
00146 
00147 wxDockPanel * wxDockWindowBase::GetDockPanel() {
00148     // return the docking panel
00149     return pClientPanel_;
00150 }
00151 
00152 void wxDockWindowBase::SetDockingInfo( wxHostInfo &hi ) {
00153     prevHost_ = hi;
00154 }
00155 
00156 void wxDockWindowBase::ClearDockingInfo() {
00157     prevHost_.Reset();
00158 }
00159 
00160 wxHostInfo & wxDockWindowBase::GetDockingInfo() {
00161     return prevHost_;
00162 }
00163 
00164 bool wxDockWindowBase::ActualShow( bool show ) {
00165     bool r = wxMiniFrame::Show( show );
00166     if( show ) {
00167         // update the panel layout
00168         pClientPanel_->UpdateSize();
00169     }
00170     visible_ = true;
00171     return r;
00172 }
00173 
00174 void wxDockWindowBase::DisableShowOverride() {
00175     disableShowOverride_ = true;
00176 }
00177 
00178 
00179 bool wxDockWindowBase::Show( bool show ) {
00180     if( disableShowOverride_ ) {
00181         return ActualShow( show );
00182     }
00183 
00184     // hook into Show() to perform extended functionality
00185     if( show ) {
00186         Appear();
00187     }
00188     else {
00189         Remove();
00190     }
00191     return false;
00192 }
00193 
00194 void wxDockWindowBase::StartDragging( int x, int y, bool needMouseCapture ) {
00195     // removes any displayed tool-tips
00196     wxToolTip::Enable( false );
00197 
00198     dragging_ = true;
00199     haveMoved_ = false;
00200     
00201     // take snapshot of starting rectangle
00202     startRect_ = GetRect();
00203     
00204     // take account of starting mouse
00205     startPoint_.x = x;
00206     startPoint_.y = y;
00207     
00208     // draw the initial drag frame (only when window is already floating)
00209     if( IsShown() ) {
00210         wxScreenDC dc;
00211         g_gdi.DrawFrame( (wxDC &)dc, startRect_.rect, false );
00212         prevRect_ = startRect_;
00213     }
00214 
00215     // we want all mouse moves
00216     if( needMouseCapture ) {
00217         CaptureMouse();
00218     }
00219 }
00220 
00221 void wxDockWindowBase::StopDragging( bool needMouseRelease ) {
00222     if( !dragging_ ) return;
00223     dragging_ = false;
00224     
00225     // clear the last drag frame
00226     if( prevRect_.valid ) {
00227         wxScreenDC dc;
00228         g_gdi.DrawFrame( (wxDC &)dc, prevRect_.rect, false );
00229     }
00230     
00231     // move window?
00232     if( dragRect_.valid ) {
00233         if( newHost_.valid ) {
00234             // apply host info
00235             pLayoutManager_->DockWindow( this, newHost_ );
00236         }
00237         else {
00238             // move
00239             Move( dragRect_.rect.x, dragRect_.rect.y );
00240             if( !IsShown() ) {
00241                 // undock window
00242                 pLayoutManager_->UndockWindow( this );
00243             }
00244         }
00245     }
00246     
00247     // clean-up
00248     startRect_.Reset();
00249     prevRect_.Reset();
00250     dragRect_.Reset();
00251     if( needMouseRelease )
00252         ReleaseMouse();
00253     newHost_.Reset();
00254     
00255     // re-enables tool-tips
00256     wxToolTip::Enable( true );
00257 
00258     haveMoved_ = false;
00259 }
00260 
00261 bool wxDockWindowBase::BlockDocking() {
00262     // optional platform implementation
00263     return false;
00264 }
00265 
00266 void wxDockWindowBase::RepeatLastMouseEvent() {
00267     if( haveMoved_ ) {
00268         OnMouseMove( lastMouseEvent_ );
00269     }
00270 }
00271 
00272 void wxDockWindowBase::OnMouseMove( wxMouseEvent &e ) {
00273     // save a copy of the mouse event
00274     haveMoved_ = true;
00275     lastMouseEvent_ = e;
00276 
00277     if( dragging_ ) {
00278         wxScreenDC dc;
00279 
00280         // get mouse co-ordinates
00281         int mx = e.GetX();
00282         int my = e.GetY();
00283         ClientToScreen( &mx, &my );
00284 
00285         // update drag rectangle
00286         newHost_.Reset();
00287         if( pLayoutManager_ ) {
00288             newHost_ = pLayoutManager_->TestForHost( mx, my );
00289             newHost_.valid &= !BlockDocking();
00290         }
00291         
00292         if( newHost_.valid  ) {
00293             // docking
00294             dragRect_ = newHost_.pHost->GetScreenArea( newHost_ );
00295         }
00296         else {
00297             // no docking 
00298             dragRect_ = GetRect();
00299             if( !IsShown() ) {
00300                 // if dragging whilst docked, auto-adjust window position
00301                 dragRect_ = GetClientRect();
00302                 
00303                 // account for offset within pane
00304                 wxPoint point( wxPoint( startPoint_.x, startPoint_.y ) );
00305                 dragRect_.rect.SetPosition( pLayoutManager_->PointFromScreen( point ) );
00306                 
00307                 // centre around cursor
00308                 dragRect_.rect.Offset( -(dragRect_.rect.width/2), -(dragRect_.rect.height/2) );
00309                 
00310                 // transpose to screen
00311                 dragRect_.rect = pLayoutManager_->RectToScreen( dragRect_.rect );
00312             }
00313             dragRect_.rect.Offset( mx-startPoint_.x, my-startPoint_.y );
00314         }
00315         
00316         // draw updated drag frame
00317         if( prevRect_.valid ) {
00318             wxScreenDC dc;
00319             g_gdi.DrawFrame( (wxDC &)dc, prevRect_.rect, false );
00320         }
00321         g_gdi.DrawFrame( (wxDC &)dc, dragRect_.rect, false );
00322 
00323         // update previous        
00324         prevRect_ = dragRect_;
00325     }
00326 }
00327 
00328 void wxDockWindowBase::OnClose( wxCloseEvent &e ) {
00329     // our close actually just hides
00330     e.Veto();
00331     Remove();
00332 
00333 }
00334 
00335 void wxDockWindowBase::createClient() {
00336     // make a client sizer
00337     pClientSizer_ = new wxBoxSizer( wxHORIZONTAL );
00338     SetSizer( pClientSizer_ );
00339     
00340     // auto-create our docking client
00341     unsigned int flags = 0x0000;
00342     (flags_ & wxDWC_NO_CONTROLS) ? flags |= wxDPC_NO_CONTROLS : 0;
00343     pClientPanel_ = new wxDockPanel( this, 0, wxT("dockpanel"), flags );
00344     pClientPanel_->Show();
00345     pClientPanel_->SetDockWindow( this );
00346     
00347     // init. the sizer
00348     pClientSizer_->Add( pClientPanel_, 1, wxGROW );
00349     Layout();
00350 }
00351 
00352 bool wxDockWindowBase::applyLastDock( bool noShowOperation ) {
00353     // dock back into host - if possible
00354     if( prevHost_.valid ) {
00355         // apply previous host info
00356         pLayoutManager_->DockWindow( this, prevHost_, noShowOperation );
00357         return true;
00358     }
00359     return false;
00360 }
00361 
00362 void wxDockWindowBase::SetDocked( bool state ) {
00363     docked_ = state;
00364 }
00365 
00366 bool wxDockWindowBase::IsDocked() {
00367     return docked_;
00368 }
00369 
00370 bool wxDockWindowBase::IsVisible() {
00371     return visible_;
00372 }
00373 

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