Files
FC1/Editor/LayoutWnd.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

628 lines
15 KiB
C++

// LayoutWnd.cpp : implementation file
//
#include "stdafx.h"
#include "LayoutWnd.h"
#include "ViewPane.h"
#include "ViewManager.h"
#include "Viewport.h"
#include "CryEditDoc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_DYNCREATE(CLayoutSplitter,CSplitterWnd)
IMPLEMENT_DYNCREATE(CLayoutWnd,CWnd)
/////////////////////////////////////////////////////////////////////////////
// CLayoutSplitter
//////////////////////////////////////////////////////////////////////////
CLayoutSplitter::CLayoutSplitter()
{
m_cxSplitter = m_cySplitter = 3 + 1 + 1;
m_cxBorderShare = m_cyBorderShare = 0;
m_cxSplitterGap = m_cySplitterGap = 3 + 1 + 1;
m_cxBorder = m_cyBorder = 1;
}
CLayoutSplitter::~CLayoutSplitter()
{
}
BEGIN_MESSAGE_MAP(CLayoutSplitter, CSplitterWnd)
//{{AFX_MSG_MAP(CLayoutSplitter)
ON_WM_SIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
void CLayoutSplitter::OnDrawSplitter(CDC* pDC, ESplitType nType, const CRect& rectArg)
{
// Let CSplitterWnd handle everything but the border-drawing
if((nType != splitBorder) || (pDC == NULL))
{
CSplitterWnd::OnDrawSplitter(pDC, nType, rectArg);
return;
}
ASSERT_VALID(pDC);
// Draw border
pDC->Draw3dRect(rectArg, GetSysColor(COLOR_BTNSHADOW), GetSysColor(COLOR_BTNHIGHLIGHT));
}
//////////////////////////////////////////////////////////////////////////
void CLayoutSplitter::OnSize(UINT nType, int cx, int cy)
{
CSplitterWnd::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
if (m_hWnd && m_pRowInfo && m_pColInfo)
{
CRect rc;
GetClientRect( rc );
int i;
int rows = GetRowCount();
int cols = GetColumnCount();
for (i = 0; i < rows; i++)
{
float idealSize = 0;
CViewPane *viewPane = (CViewPane*)GetPane(i,0);
if (viewPane)
{
CViewport *viewport = viewPane->GetViewport();
if (viewport)
idealSize = viewport->GetIdealSize().cy;
}
if (idealSize == 0)
SetRowInfo( i,rc.bottom/rows,10 );
else
SetRowInfo( i,idealSize,10 );
}
for (i = 0; i < cols; i++)
{
float idealSize = 0;
CViewPane *viewPane = (CViewPane*)GetPane(0,i);
if (viewPane)
{
CViewport *viewport = viewPane->GetViewport();
if (viewport)
idealSize = viewport->GetIdealSize().cx;
}
if (idealSize == 0)
SetColumnInfo( i,rc.right/cols,10 );
else
{
SetColumnInfo( i,idealSize,10 );
}
}
RecalcLayout();
}
}
//////////////////////////////////////////////////////////////////////////
void CLayoutSplitter::CreateLayoutView( int row,int col,int id,EViewportType viewType,CCreateContext* pContext )
{
assert( row >= 0 && row < 3 );
assert( col >= 0 && col < 3 );
CreateView( row,col,RUNTIME_CLASS(CViewPane),CSize(100,100),pContext );
CViewPane *viewPane = (CViewPane*)GetPane(row,col);
if (viewPane)
{
viewPane->SetId(id);
}
}
//////////////////////////////////////////////////////////////////////////
// CLayoutWnd
//////////////////////////////////////////////////////////////////////////
CLayoutWnd::CLayoutWnd()
{
m_splitWnd = 0;
m_splitWnd2 = 0;
m_bMaximized = false;
m_maximizedView = 0;
m_layout = (EViewLayout)-1;
m_maximizedViewId = 0;
for (int i = 0; i < sizeof(m_viewType)/sizeof(m_viewType[0]); i++)
m_viewType[i] = ET_ViewportUnknown;
}
//////////////////////////////////////////////////////////////////////////
CLayoutWnd::~CLayoutWnd()
{
if (m_splitWnd)
delete m_splitWnd;
m_splitWnd = 0;
if (m_splitWnd2)
delete m_splitWnd2;
m_splitWnd2 = 0;
}
BEGIN_MESSAGE_MAP(CLayoutWnd, CWnd)
//{{AFX_MSG_MAP(CLayoutWnd)
ON_WM_SIZE()
//}}AFX_MSG_MAP
ON_WM_DESTROY()
END_MESSAGE_MAP()
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
if (m_hWnd)
{
CRect rc;
GetClientRect( rc );
// Move primary split window.
// Secondary split window will be resized within primary.
if (m_splitWnd)
m_splitWnd->MoveWindow(rc);
// Resize maximized view.
if (m_maximizedView)
m_maximizedView->MoveWindow(rc);
}
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::UnbindViewports()
{
// First unbind all views.
for (int i = 0; i < MAX_VIEWPORTS; i++)
{
CViewPane *pViewPane = GetViewPane(i);
if (pViewPane)
{
pViewPane->AssignViewport( ET_ViewportUnknown );
}
}
if (m_maximizedView)
m_maximizedView->AssignViewport( ET_ViewportUnknown );
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::BindViewports()
{
// First unbind all views.
UnbindViewports();
for (int i = 0; i < MAX_VIEWPORTS; i++)
{
CViewPane *pViewPane = GetViewPane(i);
if (pViewPane)
{
BindViewport( pViewPane,m_viewType[pViewPane->GetId()] );
}
}
if (m_splitWnd)
m_splitWnd->SetActivePane(0,0);
//////////////////////////////////////////////////////////////////////////
if (GetIEditor()->GetViewManager()->GetViewCount() == 1)
{
//MaximizeViewport( GetIEditor()->GetViewManager()->GetView(0)->GetType() );
//return;
}
Invalidate(FALSE);
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::BindViewport( CViewPane *vp,EViewportType type )
{
assert( vp );
vp->AssignViewport( type );
vp->SetFullscren( false );
vp->ShowWindow( SW_SHOW );
m_viewType[vp->GetId()] = type;
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::BindViewport( CViewPane *vp,CViewport *pViewport )
{
//vp->AssignViewport( pViewport );
//vp->ShowWindow( SW_SHOW );
//m_viewType[vp->GetId()] = pViewport->GetType();
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::MaximizeViewport( int paneId )
{
// Ignore with full screen layout.
if (m_layout == ET_Layout0 && m_bMaximized)
return;
EViewportType type = m_viewType[paneId];
CRect rc;
GetClientRect( rc );
if (!m_bMaximized)
{
UnbindViewports();
m_maximizedViewId = paneId;
m_bMaximized = true;
if (m_maximizedView)
{
if (m_splitWnd)
m_splitWnd->ShowWindow( SW_HIDE );
if (m_splitWnd2)
m_splitWnd2->ShowWindow(SW_HIDE);
m_maximizedView->ShowWindow( SW_SHOW );
BindViewport( m_maximizedView,type );
m_maximizedView->SetFocus();
((CFrameWnd*)AfxGetMainWnd())->SetActiveView( m_maximizedView );
}
}
else
{
m_bMaximized = false;
m_maximizedViewId = 0;
UnbindViewports();
if (m_maximizedView)
m_maximizedView->ShowWindow(SW_HIDE);
if (m_splitWnd)
m_splitWnd->ShowWindow(SW_SHOW);
if (m_splitWnd2)
m_splitWnd2->ShowWindow(SW_SHOW);
BindViewports();
if (m_splitWnd)
m_splitWnd->SetActivePane(0,0);
}
RedrawWindow();
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::CreateSubSplitView( int row,int col,EViewLayout splitType,CCreateContext* pContext )
{
assert( row >= 0 && row < 3 );
assert( col >= 0 && col < 3 );
// m_viewType[row][col] = -1;
//m_secondSplitWnd = new CLayoutWnd;
//m_secondSplitWnd->CreateLayout( this,splitType,pCtx,IdFromRowCol(0,0) );
}
void CLayoutWnd::CreateLayoutView( CLayoutSplitter *wndSplitter,int row,int col,int id,EViewportType viewType,CCreateContext* pContext )
{
wndSplitter->CreateLayoutView( row,col,id,viewType,pContext );
m_viewType[id] = viewType;
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::CreateLayout( EViewLayout layout,bool bBindViewports,EViewportType defaultView )
{
UnbindViewports();
m_layout = layout;
m_bMaximized = false;
CCreateContext ctx;
ZeroStruct(ctx);
ctx.m_pNewViewClass = RUNTIME_CLASS(CViewPane);
ctx.m_pCurrentDoc = GetIEditor()->GetDocument();
ctx.m_pCurrentFrame = (CFrameWnd*)AfxGetMainWnd();
CCreateContext *pCtx = &ctx;
if (m_splitWnd)
{
m_splitWnd->ShowWindow( SW_HIDE );
m_splitWnd->DestroyWindow();
delete m_splitWnd;
m_splitWnd = 0;
}
if (m_splitWnd2)
{
delete m_splitWnd2;
m_splitWnd2 = 0;
}
if (m_maximizedView)
m_maximizedView->ShowWindow( SW_HIDE );
CRect rc;
GetClientRect(rc);
if (!m_maximizedView)
{
m_maximizedView = new CViewPane;
m_maximizedView->SetId(0);
m_maximizedView->Create( 0,0,WS_CHILD|WS_VISIBLE,rc,this,0,pCtx );
m_maximizedView->ShowWindow( SW_HIDE );
m_maximizedView->SetFullscren(true);
}
switch (layout) {
case ET_Layout0:
m_viewType[0] = defaultView;
MaximizeViewport(0);
break;
case ET_Layout1:
m_splitWnd = new CLayoutSplitter;
m_splitWnd->CreateStatic( this,1,2 );
CreateLayoutView( m_splitWnd,0,0,2,ET_ViewportMap,pCtx );
CreateLayoutView( m_splitWnd,0,1,1,defaultView,pCtx );
break;
case ET_Layout2:
m_splitWnd = new CLayoutSplitter;
m_splitWnd->CreateStatic( this,2,1 );
CreateLayoutView( m_splitWnd,0,0,2,ET_ViewportMap,pCtx );
CreateLayoutView( m_splitWnd,1,0,1,defaultView,pCtx );
break;
case ET_Layout3:
m_splitWnd = new CLayoutSplitter;
m_splitWnd->CreateStatic( this,1,2 );
CreateLayoutView( m_splitWnd,0,1,1,defaultView,pCtx );
m_splitWnd2 = new CLayoutSplitter;
m_splitWnd2->CreateStatic( m_splitWnd,2,1,WS_CHILD|WS_VISIBLE,m_splitWnd->IdFromRowCol(0,0) );
CreateLayoutView( m_splitWnd2,0,0,2,ET_ViewportXY,pCtx );
CreateLayoutView( m_splitWnd2,1,0,3,ET_ViewportXZ,pCtx );
break;
case ET_Layout4:
m_splitWnd = new CLayoutSplitter;
m_splitWnd->CreateStatic( this,1,2 );
CreateLayoutView( m_splitWnd,0,0,1,defaultView,pCtx );
m_splitWnd2 = new CLayoutSplitter;
m_splitWnd2->CreateStatic( m_splitWnd,2,1,WS_CHILD|WS_VISIBLE,m_splitWnd->IdFromRowCol(0,1) );
CreateLayoutView( m_splitWnd2,0,0,2,ET_ViewportXY,pCtx );
CreateLayoutView( m_splitWnd2,1,0,3,ET_ViewportXZ,pCtx );
break;
case ET_Layout5:
m_splitWnd = new CLayoutSplitter;
m_splitWnd->CreateStatic( this,2,1 );
CreateLayoutView( m_splitWnd,1,0,1,defaultView,pCtx );
m_splitWnd2 = new CLayoutSplitter;
m_splitWnd2->CreateStatic( m_splitWnd,1,2,WS_CHILD|WS_VISIBLE,m_splitWnd->IdFromRowCol(0,0) );
CreateLayoutView( m_splitWnd2,0,0,2,ET_ViewportXY,pCtx );
CreateLayoutView( m_splitWnd2,0,1,3,ET_ViewportXZ,pCtx );
break;
case ET_Layout6:
m_splitWnd = new CLayoutSplitter;
m_splitWnd->CreateStatic( this,2,1 );
CreateLayoutView( m_splitWnd,0,0,1,defaultView,pCtx );
m_splitWnd2 = new CLayoutSplitter;
m_splitWnd2->CreateStatic( m_splitWnd,1,2,WS_CHILD|WS_VISIBLE,m_splitWnd->IdFromRowCol(1,0) );
CreateLayoutView( m_splitWnd2,0,0,2,ET_ViewportXY,pCtx );
CreateLayoutView( m_splitWnd2,0,1,3,ET_ViewportXZ,pCtx );
break;
case ET_Layout7:
m_splitWnd = new CLayoutSplitter;
m_splitWnd->CreateStatic( this,2,2 );
CreateLayoutView( m_splitWnd,0,0,2,ET_ViewportXZ,pCtx );
CreateLayoutView( m_splitWnd,0,1,3,ET_ViewportYZ,pCtx );
CreateLayoutView( m_splitWnd,1,0,4,ET_ViewportXY,pCtx );
CreateLayoutView( m_splitWnd,1,1,1,defaultView,pCtx );
break;
case ET_Layout8:
m_splitWnd = new CLayoutSplitter;
m_splitWnd->CreateStatic( this,2,1 );
CreateLayoutView( m_splitWnd,1,0,1,defaultView,pCtx );
m_splitWnd2 = new CLayoutSplitter;
m_splitWnd2->CreateStatic( m_splitWnd,1,3,WS_CHILD|WS_VISIBLE,m_splitWnd->IdFromRowCol(0,0) );
CreateLayoutView( m_splitWnd2,0,0,2,ET_ViewportXY,pCtx );
CreateLayoutView( m_splitWnd2,0,1,3,ET_ViewportXZ,pCtx );
CreateLayoutView( m_splitWnd2,0,2,4,ET_ViewportYZ,pCtx );
break;
default:
CLogFile::FormatLine( "Trying to Create Unknown Layout %d",(int)layout );
AfxMessageBox( _T("Trying to Create Unknown Layout"),MB_OK|MB_ICONERROR );
break;
};
if (m_splitWnd)
{
m_splitWnd->MoveWindow(rc);
m_splitWnd->SetActivePane(0,0);
}
if (bBindViewports && !m_bMaximized)
BindViewports();
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::SaveConfig()
{
CWinApp *pApp = AfxGetApp();
assert( pApp );
pApp->WriteProfileInt( "Layout","Layout",(int)m_layout );
pApp->WriteProfileInt( "Layout","Maximized",(int)m_maximizedViewId );
CString str;
int v[MAX_VIEWPORTS];
for (int i = 0; i < MAX_VIEWPORTS; i++) v[i] = m_viewType[i];
str.Format( "%d,%d,%d,%d,%d,%d,%d,%d,%d",v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7],v[8] );
pApp->WriteProfileString( "Layout","Views",str );
}
//////////////////////////////////////////////////////////////////////////
bool CLayoutWnd::LoadConfig()
{
CWinApp *pApp = AfxGetApp();
assert( pApp );
int layout = pApp->GetProfileInt( "Layout","Layout",-1 );
int maximizedView = pApp->GetProfileInt( "Layout","Maximized",0 );
if (layout < 0)
return false;
CreateLayout( (EViewLayout)layout,false );
bool bRebindViewports = false;
if (m_splitWnd)
{
CString str = pApp->GetProfileString( "Layout","Views" );
if (!str.IsEmpty())
{
int v[9];
if (sscanf( str,"%d,%d,%d,%d,%d,%d,%d,%d,%d",&v[0],&v[1],&v[2],&v[3],&v[4],&v[5],&v[6],&v[7],&v[8] ) == 9)
{
bRebindViewports = true;
for (int i = 0; i < MAX_VIEWPORTS; i++)
m_viewType[i] = (EViewportType)v[i];
}
}
}
if (maximizedView > 0 && bRebindViewports)
{
MaximizeViewport( maximizedView );
}
else
{
if (bRebindViewports)
BindViewports();
else
CreateLayout( (EViewLayout)layout );
}
return true;
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::AssignViewport( CViewPane *vp,EViewportType type )
{
assert( vp );
//UnbindViewports();
if (vp == m_maximizedView)
{
BindViewport( m_maximizedView,type );
return;
}
if (type == ET_ViewportCamera)
{
// Cannot simply assign new viewport to camera.
// must swap with existing viewport that holds perspective view.
}
BindViewport( vp,type );
//BindViewports();
}
//////////////////////////////////////////////////////////////////////////
CViewPane* CLayoutWnd::GetViewPane( int id )
{
if (m_splitWnd)
{
for (int row = 0; row < m_splitWnd->GetRowCount(); row++)
for (int col = 0; col < m_splitWnd->GetColumnCount(); col++)
{
CWnd *pWnd = m_splitWnd->GetPane(row,col);
if (pWnd->IsKindOf(RUNTIME_CLASS(CViewPane)))
{
CViewPane *pane = (CViewPane*)pWnd;
if (pane && pane->GetId() == id)
return pane;
}
}
}
if (m_splitWnd2)
{
for (int row = 0; row < m_splitWnd2->GetRowCount(); row++)
for (int col = 0; col < m_splitWnd2->GetColumnCount(); col++)
{
CWnd *pWnd = m_splitWnd2->GetPane(row,col);
if (pWnd->IsKindOf(RUNTIME_CLASS(CViewPane)))
{
CViewPane *pane = (CViewPane*)pWnd;
if (pane && pane->GetId() == id)
return pane;
}
}
}
return NULL;
}
//////////////////////////////////////////////////////////////////////////
CViewPane* CLayoutWnd::FindViewByType( EViewportType type )
{
for (int i = 1; i < MAX_VIEWPORTS; i++)
{
if (m_viewType[i] == type)
{
return GetViewPane(i);
}
}
return NULL;
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::Cycle2DViewport()
{
// Cycle between 3 2D viewports.
CViewPane *vp = NULL;
vp = FindViewByType( ET_ViewportXY );
if (vp)
{
AssignViewport( vp,ET_ViewportXZ );
return;
}
vp = FindViewByType( ET_ViewportXZ );
if (vp)
{
AssignViewport( vp,ET_ViewportYZ );
return;
}
vp = FindViewByType( ET_ViewportYZ );
if (vp)
{
AssignViewport( vp,ET_ViewportXY );
return;
}
}
//////////////////////////////////////////////////////////////////////////
void CLayoutWnd::OnDestroy()
{
CWnd::OnDestroy();
// Also destroy all viewports.
for (int i = 0; i < GetIEditor()->GetViewManager()->GetViewCount(); i++)
{
GetIEditor()->GetViewManager()->GetView(i)->DestroyWindow();
}
// TODO: Add your message handler code here
}