00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00023
00024
00025 const long dockWindowStyle = (wxDEFAULT_FRAME_STYLE | 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
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
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
00082 if( pClientPanel_->IsDocked() ) {
00083 return;
00084 }
00085
00086
00087 if( !applyLastDock( true ) ) {
00088
00089 ActualShow();
00090 }
00091 }
00092 else {
00093 ActualShow();
00094 }
00095 visible_ = true;
00096 }
00097
00098 void wxDockWindowBase::Remove() {
00099 if( IsDocked() ) {
00100
00101 if( !pClientPanel_->IsDocked() ) {
00102 return;
00103 }
00104
00105 wxLayoutManager * pLayoutManager = GetLayoutManager();
00106 wxASSERT(pLayoutManager);
00107
00108
00109 pLayoutManager->UndockWindow( this, true );
00110 }
00111 else {
00112 ActualShow( false );
00113 }
00114 visible_ = false;
00115 }
00116
00117 void wxDockWindowBase::AutoFitSingleChild() {
00118
00119 wxASSERT(pClientPanel_);
00120 pClientPanel_->AutoFitSingleChild();
00121 }
00122
00123 void wxDockWindowBase::SetClient( wxWindow * pClient, bool autoPane ) {
00124
00125 pClientPanel_->SetClient( pClient, autoPane );
00126 }
00127
00128 wxWindow * wxDockWindowBase::GetClient() {
00129
00130 return pClientPanel_->GetClient();
00131 }
00132
00133 wxWindow * wxDockWindowBase::RemoveClient( wxWindow * pNewParent ) {
00134 wxWindow * pClient = GetClient();
00135
00136
00137 pClientPanel_->SetClient( NULL );
00138
00139
00140 if( pClient && pNewParent ) {
00141 pClient->Reparent( pNewParent );
00142 }
00143
00144 return pClient;
00145 }
00146
00147 wxDockPanel * wxDockWindowBase::GetDockPanel() {
00148
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
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
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
00196 wxToolTip::Enable( false );
00197
00198 dragging_ = true;
00199 haveMoved_ = false;
00200
00201
00202 startRect_ = GetRect();
00203
00204
00205 startPoint_.x = x;
00206 startPoint_.y = y;
00207
00208
00209 if( IsShown() ) {
00210 wxScreenDC dc;
00211 g_gdi.DrawFrame( (wxDC &)dc, startRect_.rect, false );
00212 prevRect_ = startRect_;
00213 }
00214
00215
00216 if( needMouseCapture ) {
00217 CaptureMouse();
00218 }
00219 }
00220
00221 void wxDockWindowBase::StopDragging( bool needMouseRelease ) {
00222 if( !dragging_ ) return;
00223 dragging_ = false;
00224
00225
00226 if( prevRect_.valid ) {
00227 wxScreenDC dc;
00228 g_gdi.DrawFrame( (wxDC &)dc, prevRect_.rect, false );
00229 }
00230
00231
00232 if( dragRect_.valid ) {
00233 if( newHost_.valid ) {
00234
00235 pLayoutManager_->DockWindow( this, newHost_ );
00236 }
00237 else {
00238
00239 Move( dragRect_.rect.x, dragRect_.rect.y );
00240 if( !IsShown() ) {
00241
00242 pLayoutManager_->UndockWindow( this );
00243 }
00244 }
00245 }
00246
00247
00248 startRect_.Reset();
00249 prevRect_.Reset();
00250 dragRect_.Reset();
00251 if( needMouseRelease )
00252 ReleaseMouse();
00253 newHost_.Reset();
00254
00255
00256 wxToolTip::Enable( true );
00257
00258 haveMoved_ = false;
00259 }
00260
00261 bool wxDockWindowBase::BlockDocking() {
00262
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
00274 haveMoved_ = true;
00275 lastMouseEvent_ = e;
00276
00277 if( dragging_ ) {
00278 wxScreenDC dc;
00279
00280
00281 int mx = e.GetX();
00282 int my = e.GetY();
00283 ClientToScreen( &mx, &my );
00284
00285
00286 newHost_.Reset();
00287 if( pLayoutManager_ ) {
00288 newHost_ = pLayoutManager_->TestForHost( mx, my );
00289 newHost_.valid &= !BlockDocking();
00290 }
00291
00292 if( newHost_.valid ) {
00293
00294 dragRect_ = newHost_.pHost->GetScreenArea( newHost_ );
00295 }
00296 else {
00297
00298 dragRect_ = GetRect();
00299 if( !IsShown() ) {
00300
00301 dragRect_ = GetClientRect();
00302
00303
00304 wxPoint point( wxPoint( startPoint_.x, startPoint_.y ) );
00305 dragRect_.rect.SetPosition( pLayoutManager_->PointFromScreen( point ) );
00306
00307
00308 dragRect_.rect.Offset( -(dragRect_.rect.width/2), -(dragRect_.rect.height/2) );
00309
00310
00311 dragRect_.rect = pLayoutManager_->RectToScreen( dragRect_.rect );
00312 }
00313 dragRect_.rect.Offset( mx-startPoint_.x, my-startPoint_.y );
00314 }
00315
00316
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
00324 prevRect_ = dragRect_;
00325 }
00326 }
00327
00328 void wxDockWindowBase::OnClose( wxCloseEvent &e ) {
00329
00330 e.Veto();
00331 Remove();
00332
00333 }
00334
00335 void wxDockWindowBase::createClient() {
00336
00337 pClientSizer_ = new wxBoxSizer( wxHORIZONTAL );
00338 SetSizer( pClientSizer_ );
00339
00340
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
00348 pClientSizer_->Add( pClientPanel_, 1, wxGROW );
00349 Layout();
00350 }
00351
00352 bool wxDockWindowBase::applyLastDock( bool noShowOperation ) {
00353
00354 if( prevHost_.valid ) {
00355
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