📄 layoutmanager.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: wxLayoutManager.cpp
// Purpose: wxLayoutManager implementation.
// Author: Mark McCormack
// Modified by:
// Created: 23/02/04
// RCS-ID:
// Copyright:
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#include <wx/layoutmanager.h>
#include <wx/dockhost.h>
#include <wx/dockpanel.h>
#include <wx/dockwindow.h>
#include <wx/slidebar.h>
#include <wx/util.h>
#include <wx/mdi.h>
#include <wx/gdicmn.h>
#include <wx/list.h>
#include <wx/listimpl.cpp>
using namespace wxUtil;
// ----------------------------------------------------------------------------
// wxOwnerEventHandler implementation
// ----------------------------------------------------------------------------
IMPLEMENT_CLASS( wxOwnerEventHandler, wxEvtHandler )
BEGIN_EVENT_TABLE( wxOwnerEventHandler, wxEvtHandler )
EVT_SIZE(wxOwnerEventHandler::OnSize)
EVT_MOVE(wxOwnerEventHandler::OnMove)
EVT_SLIDEBAR_UPDATE_LAYOUT(wxOwnerEventHandler::OnUpdateLayout)
END_EVENT_TABLE()
void wxOwnerEventHandler::OnSize( wxSizeEvent &event ) {
if( pOwner_ ) {
pOwner_->OnSize();
}
event.Skip();
}
void wxOwnerEventHandler::OnMove( wxMoveEvent &event ) {
if( pOwner_ ) {
pOwner_->OnMove();
}
event.Skip();
}
void wxOwnerEventHandler::OnUpdateLayout( wxCommandEvent& WXUNUSED(event) ) {
if( pOwner_ ) {
pOwner_->OnUpdateLayout();
}
}
// ----------------------------------------------------------------------------
// wxLayoutManager constants & wx-macros
// ----------------------------------------------------------------------------
IMPLEMENT_CLASS( wxLayoutManager, wxObject )
DEFINE_LOCAL_EVENT_TYPE( wxEVT_LAYOUT_CHANGED )
WX_DECLARE_LIST( wxDockPanel, DockPanelList );
WX_DEFINE_LIST( DockPanelList );
WX_DEFINE_LIST( DockHostList );
#define STREAM_VERSION wxT("wxDocking-Stream-v1.0")
// ----------------------------------------------------------------------------
// wxLayoutManager implementation
// ----------------------------------------------------------------------------
wxLayoutManager::wxLayoutManager( wxWindow * pOwnerFrame )
: pOwnerWindow_( pOwnerFrame ) {
Init();
// install event handler
frameEventHandler_.SetOwner( this );
pOwnerWindow_->PushEventHandler( &frameEventHandler_ );
}
wxLayoutManager::~wxLayoutManager() {
// uninstall event handler
pOwnerWindow_->RemoveEventHandler( &frameEventHandler_ );
// make sure all dockwindows extended Show() handling is turned off
for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
wxDockWindowBase * pDockWindow = node->GetData();
wxASSERT(pDockWindow);
pDockWindow->DisableShowOverride();
}
}
void wxLayoutManager::Init() {
dockHosts_.Clear();
dockWindows_.Clear();
flags_ = wxDWF_SPLITTER_BORDERS;
pAutoLayoutClientWindow_ = NULL;
}
void wxLayoutManager::SetLayout( unsigned int flags, wxWindow * pAutoLayoutClientWindow ) {
flags_ = flags;
pAutoLayoutClientWindow_ = pAutoLayoutClientWindow;
// generate internal event
settingsChanged();
}
void wxLayoutManager::AddDefaultHosts() {
// adds the standard four hosts - in the standard priority order
AddDockHost( wxTOP );
AddDockHost( wxBOTTOM );
AddDockHost( wxLEFT );
AddDockHost( wxRIGHT );
}
void wxLayoutManager::AddDockHost( wxDirection dir, int initialSize, const wxString& name ) {
// fill in name?
wxString dockName = name;
if( dockName == wxT("guessname") ) {
switch( dir ) {
case wxLEFT:
dockName = wxDEFAULT_LEFT_HOST;
break;
case wxRIGHT:
dockName = wxDEFAULT_RIGHT_HOST;
break;
case wxTOP:
dockName = wxDEFAULT_TOP_HOST;
break;
case wxBOTTOM:
dockName = wxDEFAULT_BOTTOM_HOST;
break;
default:
wxASSERT_MSG( false, _T("AddDockHost() - direction parameter not recognised") );
break;
}
}
// check for duplicate
for( DockHostList::Node *node = dockHosts_.GetFirst(); node; node = node->GetNext() ) {
wxDockHost * pDockHost = node->GetData();
if( dockName == pDockHost->GetName() || dir == pDockHost->GetDirection() ) {
wxASSERT_MSG( false, _T("AddDockHost() - direction or name already used") );
}
}
// create host
wxDockHost * pDockHost = new wxDockHost( pOwnerWindow_, 0, dir, dockName );
pDockHost->SetLayoutManager( this );
pDockHost->SetAreaSize( initialSize );
// add a host
dockHosts_.Append( pDockHost );
}
wxDockHost * wxLayoutManager::GetDockHost( const wxString& name ) {
// find dock host
for( DockHostList::Node *node = dockHosts_.GetFirst(); node; node = node->GetNext() ) {
wxDockHost * pDockHost = node->GetData();
if( name == pDockHost->GetName() ) {
return pDockHost;
}
}
return NULL;
}
wxDockHost *wxLayoutManager :: GetDockHost ( const wxDirection &_dir )
{
// find dock host
wxDockHost *pDockHost = 0;
for ( DockHostList :: Node *node = dockHosts_.GetFirst(); node; node = node -> GetNext () )
{
pDockHost = node -> GetData ();
if( pDockHost && ( _dir == pDockHost -> GetDirection () ) )
return ( pDockHost );
}
return NULL;
}
void wxLayoutManager::AddDockWindow( wxDockWindowBase * pDockWindow ) {
// check for duplicate
for( DockWindowList::Node *node = dockWindows_.GetFirst(); node; node = node->GetNext() ) {
wxDockWindowBase * pKnownDockWindow = node->GetData();
if( pDockWindow->GetName() == pKnownDockWindow->GetName() ) {
wxASSERT_MSG( false, _T("AddDockWindow() - name already used") );
}
}
// add a window
dockWindows_.Append( pDockWindow );
pDockWindow->SetDockingManager( this );
}
HostInfo wxLayoutManager::TestForHost( int sx, int sy ) {
HostInfo tHostInfo;
// test host for screen co-ordinate inside of
for( DockHostList::Node *node = dockHosts_.GetFirst(); node; node = node->GetNext() ) {
wxDockHost * pDockHost = node->GetData();
if( pDockHost->TestForPanel( sx, sy, tHostInfo ) ) {
break;
}
}
return tHostInfo;
}
wxRect wxLayoutManager::TrimDockArea( wxDockHost * pDockHost, wxRect &dockArea ) {
wxRect tDockArea( dockArea );
// test host for screen co-ordinate inside of
for( DockHostList::Node *node = dockHosts_.GetFirst(); node; node = node->GetNext() ) {
wxDockHost * pKnownDockHost = node->GetData();
if( pKnownDockHost == pDockHost ) {
// ignore all hosts after us
return tDockArea;
}
if( pKnownDockHost->IsEmpty() ) {
// ignore empty dock hosts
continue;
}
// chew of another bit
wxRect chewArea = pKnownDockHost->GetClientArea();
if( pKnownDockHost->GetDirection() == wxLEFT && pDockHost->GetDirection() != wxRIGHT) {
if( chewArea.width ) {
tDockArea.x += chewArea.width;
tDockArea.width -= chewArea.width;
}
}
if( pKnownDockHost->GetDirection() == wxRIGHT && pDockHost->GetDirection() != wxLEFT ) {
if( chewArea.width ) {
tDockArea.width -= chewArea.width + 1;
}
}
if( pKnownDockHost->GetDirection() == wxTOP && pDockHost->GetDirection() != wxBOTTOM ) {
if( chewArea.height ) {
tDockArea.y += chewArea.height;
tDockArea.height -= chewArea.height;
}
}
if( pKnownDockHost->GetDirection() == wxBOTTOM && pDockHost->GetDirection() != wxTOP ) {
if( chewArea.height ) {
tDockArea.height -= chewArea.height + 1;
}
}
}
return tDockArea;
}
wxRect wxLayoutManager::RectToScreen( wxRect &rect ) {
// convert owner (frame) rect to screen rect
wxASSERT(pOwnerWindow_);
wxRect tRect( rect );
wxPoint pos = pOwnerWindow_->ClientToScreen( tRect.GetPosition() );
tRect.SetPosition( pos );
return tRect;
}
wxPoint wxLayoutManager::PointFromScreen( wxPoint &point ) {
wxASSERT(pOwnerWindow_);
return pOwnerWindow_->ScreenToClient( point );
}
unsigned int wxLayoutManager::GetFlags() {
return flags_;
}
bool wxLayoutManager::IsPrimaryDockHost( wxDockHost * pDockHost ) {
// are we the first dock host in the list?
if( dockHosts_.IndexOf( pDockHost ) == 0 ) {
return true;
}
else {
return false;
}
}
void wxLayoutManager::SetDockArea( wxRect &rect ) {
dockArea_ = rect;
}
wxRect wxLayoutManager::GetDockArea() {
return dockArea_;
}
void wxLayoutManager::DockWindow( wxDockWindowBase * pDockWindow, HostInfo &hi, bool noHideOperation ) {
wxASSERT(hi.valid);
wxASSERT(pDockWindow);
wxDockPanel * pClient = pDockWindow->GetDockPanel();
wxASSERT(pClient);
// can't dock back into the same panel
if( hi.pPanel == pClient ) {
return;
}
// undock first if in a host
if( pClient->GetDockedHost() ) {
UndockWindow( pDockWindow, true );
}
// dock a window into a host
wxDockHost * pDockHost = hi.pHost;
pDockHost->DockPanel( pClient, hi );
if( !noHideOperation ) {
pDockWindow->ActualShow( false );
pDockWindow->SetDocked( true );
}
pDockWindow->SetDockingInfo( hi );
UpdateAllHosts( true );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -