You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1075 lines
26 KiB
C++
1075 lines
26 KiB
C++
// XTPDockingPaneLayout.cpp : implementation of the CXTPDockingPaneLayout class.
|
|
//
|
|
// This file is a part of the XTREME DOCKINGPANE MFC class library.
|
|
// (c)1998-2012 Codejock Software, All Rights Reserved.
|
|
//
|
|
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
|
|
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
|
|
// CONSENT OF CODEJOCK SOFTWARE.
|
|
//
|
|
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
|
|
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
|
|
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
|
|
// SINGLE COMPUTER.
|
|
//
|
|
// CONTACT INFORMATION:
|
|
// support@codejock.com
|
|
// http://www.codejock.com
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "Common/XTPPropExchange.h"
|
|
#include "Common/XTPColorManager.h"
|
|
#include "Common/XTPSystemHelpers.h"
|
|
|
|
#include "TabManager/XTPTabManager.h"
|
|
|
|
#include "XTPDockingPaneDefines.h"
|
|
#include "XTPDockingPaneBase.h"
|
|
#include "XTPDockingPaneBaseContainer.h"
|
|
#include "XTPDockingPaneLayout.h"
|
|
#include "XTPDockingPaneSplitterContainer.h"
|
|
#include "XTPDockingPaneTabbedContainer.h"
|
|
#include "XTPDockingPane.h"
|
|
#include "XTPDockingPaneMiniWnd.h"
|
|
#include "XTPDockingPaneManager.h"
|
|
#include "XTPDockingPaneAutoHidePanel.h"
|
|
#include "XTPDockingPaneSidePanel.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
AFX_STATIC_DATA const TCHAR _xtRootSection[] = _T("DockingPaneLayouts");
|
|
AFX_STATIC_DATA const TCHAR _xtPaneSection[] = _T("Pane-%d");
|
|
AFX_STATIC_DATA const TCHAR _xtPanes[] = _T("Panes");
|
|
AFX_STATIC_DATA const TCHAR _xtSummary[] = _T("Summary");
|
|
|
|
CXTPDockingPaneLayout::CXTPDockingPaneLayout(CXTPDockingPaneManager* pManager)
|
|
: m_pManager(pManager)
|
|
{
|
|
m_bUserLayout = TRUE;
|
|
|
|
memset(m_wndPanels, 0, sizeof(m_wndPanels));
|
|
memset(m_wndMargins, 0, sizeof(m_wndMargins));
|
|
|
|
m_pClient = m_pManager->OnCreatePane(xtpPaneTypeClient, this);
|
|
m_pTopContainer = (CXTPDockingPaneSplitterContainer*)m_pManager->OnCreatePane(xtpPaneTypeSplitterContainer, this);
|
|
m_pTopContainer->Init(m_pClient, TRUE, m_pManager->GetSite());
|
|
|
|
}
|
|
|
|
CXTPDockingPaneLayout::~CXTPDockingPaneLayout()
|
|
{
|
|
Free();
|
|
}
|
|
|
|
BOOL CXTPDockingPaneLayout::IsValid() const
|
|
{
|
|
return (m_pTopContainer != NULL) && (m_pClient != NULL)
|
|
&& (m_pClient->GetType() == xtpPaneTypeClient) && (m_pManager != NULL);
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::Free()
|
|
{
|
|
m_pTopContainer = 0;
|
|
m_pClient = 0;
|
|
|
|
while (!m_lstStack.IsEmpty())
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_lstStack.RemoveTail();
|
|
pPane->DeletePane();
|
|
}
|
|
|
|
m_lstPanes.RemoveAll();
|
|
|
|
memset(m_wndPanels, 0, sizeof(m_wndPanels));
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
SAFE_DELETE(m_wndMargins[i]);
|
|
}
|
|
}
|
|
|
|
BOOL CXTPDockingPaneLayout::_Load(CXTPPropExchange* pPX)
|
|
{
|
|
if (!pPX->OnBeforeExchange())
|
|
return FALSE;
|
|
|
|
ASSERT(pPX->IsLoading());
|
|
|
|
Free();
|
|
|
|
CXTPPropExchangeSection secSummary(pPX->GetSection(_xtSummary));
|
|
|
|
int nCount = 0;
|
|
PX_Int(&secSummary, _xtPanes, nCount);
|
|
|
|
if (nCount < 2)
|
|
return FALSE;
|
|
|
|
pPX->ExchangeSchema();
|
|
|
|
|
|
TCHAR szSection[256];
|
|
CXTPPaneIndexToPaneMap map;
|
|
|
|
for (int i = 1; i <= nCount; i++)
|
|
{
|
|
wsprintf(szSection, _xtPaneSection, i);
|
|
|
|
CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
|
|
|
|
int nType = -1;
|
|
PX_Int(&secPane, _T("Type"), nType, -1);
|
|
|
|
CXTPDockingPaneBase* pPane = m_pManager->OnCreatePane((XTPDockingPaneType)nType, this);
|
|
|
|
if (!pPane)
|
|
{
|
|
return FALSE;
|
|
}
|
|
pPane->m_nIndex = i;
|
|
map.SetAt(i, pPane);
|
|
}
|
|
|
|
ASSERT(map.GetCount() == m_lstStack.GetCount());
|
|
|
|
POSITION pos = m_lstStack.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_lstStack.GetNext(pos);
|
|
|
|
wsprintf(szSection, _xtPaneSection, pPane->m_nIndex);
|
|
|
|
CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
|
|
secPane->m_dwData = (DWORD_PTR)↦
|
|
|
|
if (!pPane->DoPropExchange(&secPane))
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
int nIndex = 0;
|
|
if (!PX_Int(&secSummary, _T("TopContainer"), nIndex))
|
|
return FALSE;
|
|
|
|
m_pTopContainer = (CXTPDockingPaneSplitterContainer*)map[nIndex];
|
|
if (!m_pTopContainer)
|
|
return FALSE;
|
|
|
|
if (!PX_Int(&secSummary, _T("Client"), nIndex))
|
|
return FALSE;
|
|
|
|
m_pClient = map[nIndex];
|
|
if (!m_pClient || m_pClient->GetType() != xtpPaneTypeClient)
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
// The main difference between the .Net versions and the normal versions of _Save is that in the .Net
|
|
// versions all the save is done is done in the exact same order of the load.
|
|
|
|
void CXTPDockingPaneLayout::_Save(CXTPPropExchange* pPX)
|
|
{
|
|
ASSERT(!pPX->IsLoading());
|
|
|
|
pPX->EmptySection();
|
|
|
|
_FreeEmptyPanes();
|
|
|
|
CXTPPropExchangeSection secSummary(pPX->GetSection(_xtSummary));
|
|
|
|
int nCount = (int)m_lstStack.GetCount();
|
|
PX_Int(&secSummary, _xtPanes, nCount);
|
|
|
|
pPX->ExchangeSchema();
|
|
|
|
|
|
TCHAR szSection[256];
|
|
|
|
// Assign an unique value to each pane
|
|
int nIndex = 1; // important
|
|
|
|
POSITION pos = m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = m_lstPanes.GetNext(pos);
|
|
pPane->m_nIndex = nIndex++;
|
|
|
|
wsprintf(szSection, _xtPaneSection, pPane->m_nIndex);
|
|
|
|
CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
|
|
int nType = pPane->m_type;
|
|
PX_Int(&secPane, _T("Type"), nType);
|
|
}
|
|
|
|
pos = m_lstStack.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_lstStack.GetNext(pos);
|
|
if (pPane->GetType() == xtpPaneTypeDockingPane) continue;
|
|
pPane->m_nIndex = nIndex++;
|
|
|
|
wsprintf(szSection, _xtPaneSection, pPane->m_nIndex);
|
|
|
|
CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
|
|
int nType = pPane->m_type;
|
|
PX_Int(&secPane, _T("Type"), nType);
|
|
}
|
|
|
|
pos = m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = m_lstPanes.GetNext(pos);
|
|
wsprintf(szSection, _xtPaneSection, pPane->m_nIndex);
|
|
|
|
CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
|
|
pPane->DoPropExchange(&secPane);
|
|
}
|
|
|
|
// Save all panes
|
|
pos = m_lstStack.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_lstStack.GetNext(pos);
|
|
if (pPane->GetType() == xtpPaneTypeDockingPane) continue;
|
|
wsprintf(szSection, _xtPaneSection, pPane->m_nIndex);
|
|
|
|
CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
|
|
pPane->DoPropExchange(&secPane);
|
|
}
|
|
|
|
PX_Int(&secSummary, _T("TopContainer"), m_pTopContainer->m_nIndex);
|
|
PX_Int(&secSummary, _T("Client"), m_pClient->m_nIndex);
|
|
|
|
}
|
|
|
|
|
|
BOOL CXTPDockingPaneLayout::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
if (pPX->IsLoading())
|
|
return _Load(pPX);
|
|
|
|
_Save(pPX);
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneLayout::Load(LPCTSTR strSection)
|
|
{
|
|
CXTPPropExchangeSection pxRoot(TRUE, _xtRootSection);
|
|
CXTPPropExchangeSection pxSection(pxRoot->GetSection(strSection));
|
|
|
|
return DoPropExchange(&pxSection);
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::Save(LPCTSTR strSection)
|
|
{
|
|
CXTPPropExchangeSection pxRoot(FALSE, _xtRootSection);
|
|
CXTPPropExchangeSection pxSection(pxRoot->GetSection(strSection));
|
|
|
|
DoPropExchange(&pxSection);
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::Serialize(CArchive& ar)
|
|
{
|
|
CXTPPropExchangeArchive px(ar);
|
|
DoPropExchange(&px);
|
|
}
|
|
|
|
|
|
#ifndef _XTP_EXCLUDE_XML
|
|
|
|
BOOL CXTPDockingPaneLayout::LoadFromNode(XTPXML::IXMLDOMNode* xmlNode, LPCTSTR strSection)
|
|
{
|
|
if (xmlNode == 0)
|
|
return FALSE;
|
|
|
|
CXTPPropExchangeXMLNode px(TRUE, xmlNode, strSection);
|
|
return DoPropExchange(&px);
|
|
}
|
|
|
|
BOOL CXTPDockingPaneLayout::LoadFromFile(LPCTSTR strFileName, LPCTSTR strSection)
|
|
{
|
|
CXTPPropExchangeXMLNode px(TRUE, 0, _xtRootSection);
|
|
if (!px.LoadFromFile(strFileName))
|
|
return FALSE;
|
|
|
|
CXTPPropExchangeSection pxSection(px.GetSection(strSection));
|
|
if (!pxSection->OnBeforeExchange())
|
|
return FALSE;
|
|
|
|
return DoPropExchange(&pxSection);
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::SaveToNode (XTPXML::IXMLDOMNode* xmlNode, LPCTSTR strSection)
|
|
{
|
|
if (xmlNode == 0)
|
|
return;
|
|
|
|
CXTPPropExchangeXMLNode px(FALSE, xmlNode, strSection);
|
|
DoPropExchange(&px);
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::SaveToFile (LPCTSTR strFileName, LPCTSTR strSection)
|
|
{
|
|
CXTPPropExchangeXMLNode px(FALSE, 0, _xtRootSection);
|
|
|
|
CXTPPropExchangeSection pxSection(px.GetSection(strSection));
|
|
DoPropExchange(&pxSection);
|
|
|
|
px.SaveToFile(strFileName);
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
BOOL CXTPDockingPaneBase::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
PX_Long(pPX, _T("DockingCX"), m_szDocking.cx, 0);
|
|
PX_Long(pPX, _T("DockingCY"), m_szDocking.cy, 0);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPDockingPane::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
CXTPDockingPaneBase::DoPropExchange(pPX);
|
|
|
|
if (pPX->IsStoring())
|
|
{
|
|
CString strTitle = m_strTitle + '\n' + m_strTabCaption + '\n' + m_strTitleToolTip;
|
|
PX_String(pPX, _T("Title"), strTitle);
|
|
}
|
|
else
|
|
{
|
|
CString strTitle;
|
|
PX_String(pPX, _T("Title"), strTitle);
|
|
|
|
AfxExtractSubString(m_strTitle, strTitle, 0, '\n');
|
|
AfxExtractSubString(m_strTabCaption, strTitle, 1, '\n');
|
|
AfxExtractSubString(m_strTitleToolTip, strTitle, 2, '\n');
|
|
}
|
|
|
|
PX_Int(pPX, _T("ID"), m_nID, 0);
|
|
|
|
PX_Int(pPX, _T("IconID"), m_nIconID, -1);
|
|
PX_ULong(pPX, _T("Options"), m_dwOptions, 0);
|
|
|
|
int nIndex = 0;
|
|
CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
|
|
|
|
if (!pPX->IsLoading())
|
|
{
|
|
XTP_DOCKINGPANE_INFO* pInfo = m_pLayout->FindPaneInfo(this);
|
|
ASSERT(pInfo);
|
|
if (pInfo)
|
|
{
|
|
|
|
nIndex = pInfo->pDockingHolder ? pInfo->pDockingHolder->m_nIndex : 0;
|
|
PX_Int(pPX, _T("DockingHolder"), nIndex, 0);
|
|
nIndex = pInfo->pFloatingHolder ? pInfo->pFloatingHolder->m_nIndex : 0;
|
|
PX_Int(pPX, _T("FloatingHolder"), nIndex, 0);
|
|
nIndex = pInfo->pLastHolder ? pInfo->pLastHolder->m_nIndex : 0;
|
|
PX_Int(pPX, _T("LastHolder"), nIndex, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
XTP_DOCKINGPANE_INFO info (this);
|
|
|
|
PX_Int(pPX, _T("DockingHolder"), nIndex, 0);
|
|
if (nIndex) info.pDockingHolder = (CXTPDockingPaneBase*)(*pMap)[nIndex];
|
|
PX_Int(pPX, _T("FloatingHolder"), nIndex, 0);
|
|
if (nIndex) info.pFloatingHolder = (CXTPDockingPaneBase*)(*pMap)[nIndex];
|
|
PX_Int(pPX, _T("LastHolder"), nIndex, 0);
|
|
if (nIndex) info.pLastHolder = (CXTPDockingPaneBase*)(*pMap)[nIndex];
|
|
m_pLayout->m_lstPanes.AddTail(info);
|
|
|
|
}
|
|
|
|
PX_Long(pPX, _T("MinTrackX"), m_ptMinTrackSize.x, 0);
|
|
PX_Long(pPX, _T("MinTrackY"), m_ptMinTrackSize.y, 0);
|
|
PX_Long(pPX, _T("MaxTrackX"), m_ptMaxTrackSize.x, 32000);
|
|
PX_Long(pPX, _T("MaxTrackY"), m_ptMaxTrackSize.y, 32000);
|
|
|
|
if (pPX->GetSchema() > _XTP_SCHEMA_97)
|
|
{
|
|
PX_DWord(pPX, _T("TabColor"), (DWORD&)m_clrItemTab, COLORREF_NULL);
|
|
PX_Int(pPX, _T("HelpId"), m_nIDHelp, 0);
|
|
|
|
DWORD dwData = (DWORD)m_dwData;
|
|
PX_DWord(pPX, _T("Tag"), dwData, 0);
|
|
if (pPX->IsLoading()) m_dwData = dwData;
|
|
}
|
|
|
|
return m_nID > 0;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneSplitterContainer::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
CXTPDockingPaneBase::DoPropExchange(pPX);
|
|
|
|
PX_Bool(pPX, _T("Horiz"), m_bHoriz, FALSE);
|
|
|
|
int nCount = 0;
|
|
|
|
if (!pPX->IsLoading())
|
|
{
|
|
nCount = (int)m_lstPanes.GetCount();
|
|
PX_Int(pPX, _xtPanes, nCount);
|
|
|
|
int nIndex = 1;
|
|
TCHAR szPane[256];
|
|
POSITION pos = m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_lstPanes.GetNext(pos);
|
|
wsprintf(szPane, _xtPaneSection, nIndex++);
|
|
|
|
PX_Int(pPX, szPane, pPane->m_nIndex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PX_Int(pPX, _xtPanes, nCount, 0);
|
|
|
|
int nIndex = 0;
|
|
TCHAR szPane[256];
|
|
CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
|
|
|
|
for (int i = 1; i <= nCount; i++)
|
|
{
|
|
wsprintf(szPane, _xtPaneSection, i);
|
|
PX_Int(pPX, szPane, nIndex, 0);
|
|
ASSERT(nIndex > 0);
|
|
|
|
CXTPDockingPaneBase* pPane = NULL;
|
|
ASSERT(pMap->Lookup(nIndex, pPane));
|
|
|
|
pPane = (CXTPDockingPaneBase*)((*pMap)[nIndex]);
|
|
if (!pPane) return FALSE;
|
|
|
|
_InsertPane(pPane);
|
|
}
|
|
|
|
ASSERT(nCount > 0);
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneSidePanel::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
CXTPDockingPaneBase::DoPropExchange(pPX);
|
|
int direction = m_direction;
|
|
|
|
PX_Int(pPX, _T("Direction"), direction);
|
|
PX_Rect(pPX, _T("WindowRect"), m_rcWindow, CRect(0, 0, 0, 0));
|
|
PX_Bool(pPX, _T("Collapsed"), m_bCollapsed, FALSE);
|
|
|
|
if (!pPX->IsLoading())
|
|
{
|
|
int nTopContainer = GetTopContainer() ? GetTopContainer()->m_nIndex : 0;
|
|
PX_Int(pPX, _T("TopContaner"), nTopContainer);
|
|
}
|
|
else
|
|
{
|
|
m_direction = (XTPDockingPaneDirection)direction;
|
|
|
|
int nTopContainer = 0;
|
|
PX_Int(pPX, _T("TopContaner"), nTopContainer);
|
|
|
|
if (nTopContainer == 0)
|
|
return FALSE;
|
|
|
|
CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
|
|
|
|
CXTPDockingPaneBase* pTop = (CXTPDockingPaneBase*)(*pMap)[nTopContainer];
|
|
if (!pTop || pTop->GetType() != xtpPaneTypeTabbedContainer)
|
|
return FALSE;
|
|
|
|
_InsertPane(pTop);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneAutoHidePanel::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
CXTPDockingPaneBase::DoPropExchange(pPX);
|
|
|
|
int direction = m_direction;
|
|
PX_Int(pPX, _T("Direction"), direction);
|
|
|
|
int nCount = 0;
|
|
|
|
if (!pPX->IsLoading())
|
|
{
|
|
nCount = (int)m_lstPanes.GetCount();
|
|
PX_Int(pPX, _xtPanes, nCount);
|
|
|
|
int nIndex = 1;
|
|
TCHAR szPane[256];
|
|
POSITION pos = m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_lstPanes.GetNext(pos);
|
|
wsprintf(szPane, _xtPaneSection, nIndex++);
|
|
PX_Int(pPX, szPane, pPane->m_nIndex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_direction = (XTPDockingPaneDirection)direction;
|
|
|
|
PX_Int(pPX, _xtPanes, nCount, 0);
|
|
|
|
int nIndex = 0;
|
|
TCHAR szPane[256];
|
|
CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
|
|
|
|
for (int i = 1; i <= nCount; i++)
|
|
{
|
|
wsprintf(szPane, _xtPaneSection, i);
|
|
PX_Int(pPX, szPane, nIndex, 0);
|
|
ASSERT(nIndex > 0);
|
|
|
|
CXTPDockingPaneBase* pPane = NULL;
|
|
ASSERT(pMap->Lookup(nIndex, pPane));
|
|
|
|
pPane = (CXTPDockingPaneBase*)((*pMap)[nIndex]);
|
|
if (!pPane) return FALSE;
|
|
|
|
_InsertPane(pPane);
|
|
}
|
|
|
|
m_pLayout->m_wndPanels[m_direction] = this;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneTabbedContainer::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
CXTPDockingPaneBase::DoPropExchange(pPX);
|
|
|
|
int nCount, nSelected;
|
|
|
|
if (!pPX->IsLoading())
|
|
{
|
|
nCount = (int)m_lstPanes.GetCount();
|
|
PX_Int(pPX, _xtPanes, nCount);
|
|
|
|
nSelected = m_pSelectedPane ? m_pSelectedPane->m_nIndex : 0;
|
|
PX_Int(pPX, _T("Selected"), nSelected, 0);
|
|
|
|
PX_Bool(pPX, _T("Maximized"), m_bMaximized, FALSE);
|
|
|
|
POSITION pos = m_lstPanes.GetHeadPosition();
|
|
int nIndex = 1;
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_lstPanes.GetNext(pos);
|
|
|
|
TCHAR szPane[256];
|
|
wsprintf(szPane, _xtPaneSection, nIndex++);
|
|
|
|
PX_Int(pPX, szPane, pPane->m_nIndex);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
PX_Int(pPX, _xtPanes, nCount);
|
|
PX_Int(pPX, _T("Selected"), nSelected, 0);
|
|
|
|
if (pPX->GetSchema() > _XTP_SCHEMA_1122)
|
|
{
|
|
PX_Bool(pPX, _T("Maximized"), m_bMaximized, FALSE);
|
|
}
|
|
|
|
TCHAR szPane[256];
|
|
CXTPDockingPane* pSelected = NULL;
|
|
int nIndex = 0;
|
|
CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
|
|
|
|
for (int i = 1; i <= nCount; i++)
|
|
{
|
|
wsprintf(szPane, _xtPaneSection, i);
|
|
PX_Int(pPX, szPane, nIndex, 0);
|
|
ASSERT(nIndex > 0);
|
|
|
|
CXTPDockingPaneBase* pPane = NULL;
|
|
ASSERT(pMap->Lookup(nIndex, pPane));
|
|
|
|
pPane = (CXTPDockingPaneBase*)((*pMap)[nIndex]);
|
|
|
|
if (!pPane || pPane->GetType() != xtpPaneTypeDockingPane) return FALSE;
|
|
|
|
_InsertPane((CXTPDockingPane*)pPane);
|
|
|
|
if (nIndex == nSelected) pSelected = (CXTPDockingPane*)pPane;
|
|
}
|
|
|
|
if (pSelected)
|
|
{
|
|
SelectPane(pSelected);
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXTPDockingPaneMiniWnd::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
CXTPDockingPaneBase::DoPropExchange(pPX);
|
|
|
|
PX_Long(pPX, _T("WindowRectTopPos"), m_rcWindow.top);
|
|
PX_Long(pPX, _T("WindowRectBottomPos"), m_rcWindow.bottom);
|
|
PX_Long(pPX, _T("WindowRectLeftPos"), m_rcWindow.left);
|
|
PX_Long(pPX, _T("WindowRectRightPos"), m_rcWindow.right);
|
|
PX_Bool(pPX, _T("Collapsed"), m_bCollapsed, FALSE);
|
|
PX_Int(pPX, _T("ExpandedHeight"), m_nExpandedHeight, 0);
|
|
|
|
if (!pPX->IsLoading())
|
|
{
|
|
int nTopContainer = m_pTopContainer ? m_pTopContainer->m_nIndex : 0;
|
|
PX_Int(pPX, _T("TopContaner"), nTopContainer);
|
|
}
|
|
else
|
|
{
|
|
int nTopContainer = 0;
|
|
PX_Int(pPX, _T("TopContaner"), nTopContainer);
|
|
|
|
if (nTopContainer == 0)
|
|
return FALSE;
|
|
|
|
CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
|
|
|
|
CXTPDockingPaneBase* pTop = (CXTPDockingPaneBase*)(*pMap)[nTopContainer];
|
|
if (!pTop || pTop->GetType() != xtpPaneTypeSplitterContainer)
|
|
return FALSE;
|
|
|
|
m_pTopContainer = (CXTPDockingPaneSplitterContainer*)pTop;
|
|
m_pTopContainer->m_pParentContainer = this;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::Copy(const CXTPDockingPaneLayout* pLayout)
|
|
{
|
|
Free();
|
|
|
|
CXTPPaneToPaneMap map;
|
|
|
|
// Clone them
|
|
POSITION pos = pLayout->m_lstStack.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = pLayout->m_lstStack.GetNext(pos);
|
|
if (pPane->m_pParentContainer == NULL) // hidden pane, top pane, miniwnd.
|
|
{
|
|
pPane->Clone(this, &map);
|
|
}
|
|
}
|
|
|
|
ASSERT(map.GetCount() == pLayout->m_lstStack.GetCount());
|
|
ASSERT(map.Lookup(pLayout->m_pClient, m_pClient));
|
|
ASSERT(map.Lookup(pLayout->m_pTopContainer, (CXTPDockingPaneBase*&)m_pTopContainer));
|
|
|
|
m_pClient = map[pLayout->m_pClient];
|
|
m_pTopContainer = (CXTPDockingPaneSplitterContainer*)map[pLayout->m_pTopContainer];
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
if (pLayout->m_wndPanels[i]) m_wndPanels[i] = (CXTPDockingPaneAutoHidePanel*)map[pLayout->m_wndPanels[i]];
|
|
|
|
// Map Holders
|
|
pos = pLayout->m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
XTP_DOCKINGPANE_INFO& info = pLayout->GetPaneList().GetNext(pos);
|
|
XTP_DOCKINGPANE_INFO infoCopy;
|
|
ASSERT(map.Lookup((CXTPDockingPaneBase*)info.pPane, (CXTPDockingPaneBase*&)infoCopy.pPane));
|
|
|
|
infoCopy.pPane = (CXTPDockingPane*)map[(CXTPDockingPaneBase*)info.pPane];
|
|
|
|
if (info.pDockingHolder) infoCopy.pDockingHolder = (CXTPDockingPaneBase*)map[info.pDockingHolder];
|
|
if (info.pLastHolder) infoCopy.pLastHolder = (CXTPDockingPaneBase*)map[info.pLastHolder];
|
|
if (info.pFloatingHolder) infoCopy.pFloatingHolder = (CXTPDockingPaneBase*)map[info.pFloatingHolder];
|
|
|
|
m_lstPanes.AddTail(infoCopy);
|
|
}
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::_FreeEmptyPanes()
|
|
{
|
|
WORD w;
|
|
CMapPtrToWord map;
|
|
|
|
POSITION pos = m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
XTP_DOCKINGPANE_INFO& info = m_lstPanes.GetNext(pos);
|
|
map.SetAt(info.pDockingHolder, TRUE);
|
|
map.SetAt(info.pFloatingHolder, TRUE);
|
|
map.SetAt(info.pPane->m_pParentContainer, TRUE);
|
|
}
|
|
|
|
BOOL bFound = TRUE;
|
|
|
|
while (bFound)
|
|
{
|
|
bFound = FALSE;
|
|
|
|
POSITION posRemove = pos = m_lstStack.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneBase* pPane = m_lstStack.GetNext(pos);
|
|
CXTPDockingPaneBase* pParentContainer = pPane->m_pParentContainer;
|
|
|
|
switch (pPane->GetType())
|
|
{
|
|
case xtpPaneTypeTabbedContainer:
|
|
if (!map.Lookup(pPane, w))
|
|
{
|
|
|
|
SAFE_CALLPTR(pParentContainer, RemovePane(pPane));
|
|
|
|
m_lstStack.RemoveAt(posRemove);
|
|
pPane->DeletePane();
|
|
bFound = TRUE;
|
|
}
|
|
break;
|
|
|
|
case xtpPaneTypeSplitterContainer:
|
|
if (((CXTPDockingPaneSplitterContainer*)pPane)->m_lstPanes.GetCount() == 0)
|
|
{
|
|
SAFE_CALLPTR(pParentContainer, RemovePane(pPane));
|
|
|
|
m_lstStack.RemoveAt(posRemove);
|
|
pPane->DeletePane();
|
|
bFound = TRUE;
|
|
}
|
|
else if (pParentContainer && (pParentContainer->GetType() == xtpPaneTypeSplitterContainer)
|
|
&& (((CXTPDockingPaneSplitterContainer*)pPane)->m_lstPanes.GetCount() == 1)
|
|
&& (((CXTPDockingPaneSplitterContainer*)pParentContainer)->m_lstPanes.GetCount() == 1))
|
|
{
|
|
CXTPDockingPaneBase* pChildPane = ((CXTPDockingPaneSplitterContainer*)pPane)->m_lstPanes.RemoveHead();
|
|
((CXTPDockingPaneSplitterContainer*)pParentContainer)->m_lstPanes.RemoveHead();
|
|
((CXTPDockingPaneSplitterContainer*)pParentContainer)->m_lstPanes.AddHead(pChildPane);
|
|
pChildPane->m_pParentContainer = pParentContainer;
|
|
|
|
m_lstStack.RemoveAt(posRemove);
|
|
pPane->DeletePane();
|
|
bFound = TRUE;
|
|
|
|
}
|
|
break;
|
|
|
|
case xtpPaneTypeMiniWnd:
|
|
if (((CXTPDockingPaneMiniWnd*)pPane)->m_pTopContainer == NULL)
|
|
{
|
|
m_lstStack.RemoveAt(posRemove);
|
|
pPane->DeletePane();
|
|
bFound = TRUE;
|
|
}
|
|
break;
|
|
|
|
case xtpPaneTypeSidePanel:
|
|
if (((CXTPDockingPaneSidePanel*)pPane)->m_lstPanes.GetCount() == 0)
|
|
{
|
|
m_lstStack.RemoveAt(posRemove);
|
|
pPane->DeletePane();
|
|
bFound = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
posRemove = pos;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
XTP_DOCKINGPANE_INFO* CXTPDockingPaneLayout::FindPaneInfo(CXTPDockingPane* pPane)
|
|
{
|
|
POSITION pos = m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
XTP_DOCKINGPANE_INFO& info = m_lstPanes.GetNext(pos);
|
|
|
|
if (info.pPane == pPane)
|
|
return &info;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
XTPDockingPaneDirection CXTPDockingPaneLayout::_GetPaneDirection(const CXTPDockingPaneBase* pPane) const
|
|
{
|
|
if (pPane->GetType() == xtpPaneTypeMiniWnd)
|
|
return (XTPDockingPaneDirection)4;
|
|
|
|
if (!pPane->m_pParentContainer || pPane->GetType() == xtpPaneTypeClient)
|
|
return (XTPDockingPaneDirection)-1;
|
|
|
|
if (pPane->m_pParentContainer->GetType() == xtpPaneTypeAutoHidePanel)
|
|
{
|
|
return ((CXTPDockingPaneAutoHidePanel*)pPane->m_pParentContainer)->m_direction;
|
|
}
|
|
|
|
if (pPane->GetType() == xtpPaneTypeSidePanel)
|
|
{
|
|
return ((CXTPDockingPaneSidePanel*)pPane)->m_direction;
|
|
}
|
|
|
|
if (pPane->m_pParentContainer->GetType() == xtpPaneTypeSplitterContainer)
|
|
{
|
|
POSITION pos = pPane->m_pParentContainer->ContainPane(m_pClient);
|
|
if (pos)
|
|
{
|
|
CXTPDockingPaneSplitterContainer* pSplitter = (CXTPDockingPaneSplitterContainer*)pPane->m_pParentContainer;
|
|
|
|
if (pSplitter->_Before(pPane, pos))
|
|
{
|
|
return pSplitter->IsHoriz() ? xtpPaneDockLeft : xtpPaneDockTop;
|
|
|
|
}
|
|
else
|
|
{
|
|
return pSplitter->IsHoriz() ? xtpPaneDockRight : xtpPaneDockBottom;
|
|
}
|
|
}
|
|
}
|
|
return _GetPaneDirection(pPane->m_pParentContainer);
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::_AddPanesTo(CXTPDockingPaneTabbedContainer* pContainer, CXTPDockingPaneBaseList& lst, DWORD dwIgnoredOptions)
|
|
{
|
|
POSITION pos = lst.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPane* pPane = (CXTPDockingPane*)lst.GetNext(pos);
|
|
|
|
if ((((CXTPDockingPane*)pPane)->GetOptions() & dwIgnoredOptions) == 0)
|
|
{
|
|
SAFE_CALLPTR(pPane->m_pParentContainer, RemovePane(pPane));
|
|
pContainer->_InsertPane(pPane);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CXTPDockingPaneLayout::_FindTabbedPaneToHide(CXTPDockingPaneAutoHidePanel* pPanel, CXTPDockingPaneBase* pPane)
|
|
{
|
|
CXTPDockingPaneBaseList lst;
|
|
pPane->FindPane(xtpPaneTypeDockingPane, &lst);
|
|
|
|
if (lst.IsEmpty())
|
|
return FALSE;
|
|
|
|
CXTPDockingPane* pPanePrimary = (CXTPDockingPane*)lst.GetHead();
|
|
XTP_DOCKINGPANE_INFO* pInfo = FindPaneInfo(pPanePrimary);
|
|
if (!pInfo || pInfo->pDockingHolder == NULL)
|
|
return FALSE;
|
|
|
|
POSITION pos = pPanel->m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)pPanel->m_lstPanes.GetNext(pos);
|
|
CXTPDockingPane* pContainerPane = (CXTPDockingPane*)pContainer->GetFirstPane();
|
|
if (pContainerPane)
|
|
{
|
|
XTP_DOCKINGPANE_INFO* pContanerPaneInfo = FindPaneInfo(pContainerPane);
|
|
|
|
if (pContanerPaneInfo && pContanerPaneInfo->pDockingHolder == pInfo->pDockingHolder)
|
|
{
|
|
_AddPanesTo(pContainer, lst, xtpPaneNoHideable);
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::HidePane(CXTPDockingPaneBase* pPane)
|
|
{
|
|
ASSERT(!m_bUserLayout);
|
|
|
|
XTPDockingPaneDirection direction = _GetPaneDirection(pPane);
|
|
if (direction < 0 || direction >= 4)
|
|
direction = xtpPaneDockLeft;
|
|
|
|
if (m_wndPanels[direction] == 0)
|
|
{
|
|
m_wndPanels[direction] = (CXTPDockingPaneAutoHidePanel*)m_pManager->
|
|
OnCreatePane(xtpPaneTypeAutoHidePanel, this);
|
|
m_wndPanels[direction]->m_direction = direction;
|
|
}
|
|
|
|
if (_FindTabbedPaneToHide(m_wndPanels[direction], pPane))
|
|
return;
|
|
|
|
if (pPane->GetType() == xtpPaneTypeDockingPane)
|
|
{
|
|
pPane->m_pParentContainer->RemovePane(pPane);
|
|
|
|
CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)m_pManager->
|
|
OnCreatePane(xtpPaneTypeTabbedContainer, this);
|
|
pContainer->Init((CXTPDockingPane*)pPane, m_pManager->GetSite());
|
|
|
|
pPane = pContainer;
|
|
|
|
}
|
|
else if (pPane->GetType() == xtpPaneTypeTabbedContainer)
|
|
{
|
|
pPane = ((CXTPDockingPaneBase*)pPane)->Clone(this, 0, xtpPaneNoHideable);
|
|
}
|
|
|
|
m_wndPanels[direction]->_InsertPane(pPane);
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::RepositionMargins(CRect& rect, const CRect& rcClientMargins)
|
|
{
|
|
int i;
|
|
|
|
if (rcClientMargins.IsRectNull())
|
|
{
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
SAFE_DELETE(m_wndMargins[i]);
|
|
}
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
if (m_wndMargins[i] == 0)
|
|
{
|
|
m_wndMargins[i] = new CXTPDockingPaneSplitterWnd();
|
|
m_wndMargins[i]->Create(m_pManager, i == xtpPaneDockTop || i == xtpPaneDockBottom);
|
|
}
|
|
}
|
|
|
|
CRect rcClient(rect);
|
|
rcClient.DeflateRect(rcClientMargins);
|
|
|
|
m_wndMargins[xtpPaneDockLeft]->MoveWindow(CRect(rect.left, rect.top, rcClient.left, rect.bottom));
|
|
m_wndMargins[xtpPaneDockRight]->MoveWindow(CRect(rcClient.right , rect.top, rect.right, rect.bottom));
|
|
m_wndMargins[xtpPaneDockTop]->MoveWindow(CRect(rcClient.left, rect.top, rcClient.right, rcClient.top));
|
|
m_wndMargins[xtpPaneDockBottom]->MoveWindow(CRect(rcClient.left, rcClient.bottom, rcClient.right, rect.bottom));
|
|
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
m_wndMargins[i]->Invalidate(FALSE);
|
|
}
|
|
|
|
rect = rcClient;
|
|
}
|
|
|
|
|
|
void CXTPDockingPaneLayout::OnSizeParent(CWnd* pParent, CRect rect, LPVOID lParam)
|
|
{
|
|
AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
SAFE_CALLPTR(m_wndPanels[i], OnSizeParentEx(pParent, rect, lParam));
|
|
}
|
|
|
|
int nMargin = m_pManager->GetClientMargin();
|
|
CRect rcClientMargins(nMargin, nMargin, nMargin, nMargin);
|
|
|
|
if (lpLayout->hDWP != NULL)
|
|
{
|
|
RepositionMargins(rect, rcClientMargins);
|
|
}
|
|
else
|
|
{
|
|
rect.DeflateRect(rcClientMargins);
|
|
}
|
|
|
|
m_pClient->OnSizeParent(pParent, rect, lParam);
|
|
m_pTopContainer->OnSizeParent(pParent, rect, lParam);
|
|
|
|
if (lpLayout->hDWP)
|
|
{
|
|
CXTPDockingPaneSidePanel::OnSizeParentEx(m_pManager, pParent, lpLayout->rect);
|
|
}
|
|
}
|
|
|
|
CXTPDockingPane* CXTPDockingPaneLayout::FindPane(int nID) const
|
|
{
|
|
|
|
POSITION pos = m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
XTP_DOCKINGPANE_INFO info = m_lstPanes.GetNext(pos);
|
|
CXTPDockingPane* pPane = info.pPane;
|
|
|
|
if (pPane->GetID() == nID)
|
|
return pPane;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::DestroyPane(CXTPDockingPane* pPane)
|
|
{
|
|
if (pPane == NULL) return;
|
|
|
|
SAFE_CALLPTR(pPane->m_pParentContainer, RemovePane(pPane));
|
|
|
|
POSITION pos = m_lstPanes.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
if (m_lstPanes.GetAt(pos) == pPane)
|
|
{
|
|
m_lstPanes.RemoveAt(pos);
|
|
break;
|
|
}
|
|
m_lstPanes.GetNext(pos);
|
|
}
|
|
|
|
pos = m_lstStack.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
if (m_lstStack.GetAt(pos) == pPane)
|
|
{
|
|
m_lstStack.RemoveAt(pos);
|
|
break;
|
|
}
|
|
m_lstStack.GetNext(pos);
|
|
}
|
|
((CXTPDockingPane*)pPane)->InternalRelease();
|
|
_FreeEmptyPanes();
|
|
|
|
}
|
|
|
|
void CXTPDockingPaneLayout::MoveToTail(CXTPDockingPaneBase* pPane)
|
|
{
|
|
POSITION pos = m_lstStack.GetHeadPosition();
|
|
while (pos)
|
|
{
|
|
if (m_lstStack.GetAt(pos) == pPane)
|
|
{
|
|
m_lstStack.RemoveAt(pos);
|
|
m_lstStack.AddTail(pPane);
|
|
return;
|
|
}
|
|
m_lstStack.GetNext(pos);
|
|
}
|
|
}
|
|
|