XTPDockingPaneLayout.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:26k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPDockingPaneLayout.cpp : implementation of the CXTPDockingPaneLayout class.
  2. //
  3. // This file is a part of the XTREME DOCKINGPANE MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Common/XTPVC80Helpers.h"
  22. #include "TabManager/XTPTabManager.h"
  23. #include "Common/XTPPropExchange.h"
  24. #include "XTPDockingPaneLayout.h"
  25. #include "XTPDockingPaneBase.h"
  26. #include "XTPDockingPaneSplitterContainer.h"
  27. #include "XTPDockingPaneTabbedContainer.h"
  28. #include "XTPDockingPane.h"
  29. #include "XTPDockingPaneMiniWnd.h"
  30. #include "XTPDockingPaneManager.h"
  31. #include "XTPDockingPaneAutoHidePanel.h"
  32. #include "XTPDockingPaneSidePanel.h"
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. AFX_STATIC_DATA const TCHAR _xtRootSection[] = _T("DockingPaneLayouts");
  39. AFX_STATIC_DATA const TCHAR _xtPaneSection[] = _T("Pane-%d");
  40. AFX_STATIC_DATA const TCHAR _xtPanes[] = _T("Panes");
  41. AFX_STATIC_DATA const TCHAR _xtSummary[] = _T("Summary");
  42. CXTPDockingPaneLayout::CXTPDockingPaneLayout(CXTPDockingPaneManager* pManager)
  43. : m_pManager(pManager)
  44. {
  45. m_bUserLayout = TRUE;
  46. memset(m_wndPanels, 0, sizeof(m_wndPanels));
  47. memset(m_wndMargins, 0, sizeof(m_wndMargins));
  48. m_pClient = m_pManager->OnCreatePane(xtpPaneTypeClient, this);
  49. m_pTopContainer = (CXTPDockingPaneSplitterContainer*)m_pManager->OnCreatePane(xtpPaneTypeSplitterContainer, this);
  50. m_pTopContainer->Init(m_pClient, TRUE, m_pManager->GetSite());
  51. }
  52. CXTPDockingPaneLayout::~CXTPDockingPaneLayout()
  53. {
  54. Free();
  55. }
  56. BOOL CXTPDockingPaneLayout::IsValid() const
  57. {
  58. return (m_pTopContainer != NULL) && (m_pClient != NULL)
  59. && (m_pClient->GetType() == xtpPaneTypeClient) && (m_pManager != NULL);
  60. }
  61. void CXTPDockingPaneLayout::Free()
  62. {
  63. m_pTopContainer = 0;
  64. m_pClient = 0;
  65. while (!m_lstStack.IsEmpty())
  66. {
  67. CXTPDockingPaneBase* pPane = m_lstStack.RemoveTail();
  68. pPane->DeletePane();
  69. }
  70. m_lstPanes.RemoveAll();
  71. memset(m_wndPanels, 0, sizeof(m_wndPanels));
  72. for (int i = 0; i < 4; i++)
  73. {
  74. SAFE_DELETE(m_wndMargins[i]);
  75. }
  76. }
  77. BOOL CXTPDockingPaneLayout::_Load(CXTPPropExchange* pPX)
  78. {
  79. if (!pPX->OnBeforeExchange())
  80. return FALSE;
  81. ASSERT(pPX->IsLoading());
  82. Free();
  83. CXTPPropExchangeSection secSummary(pPX->GetSection(_xtSummary));
  84. int nCount = 0;
  85. PX_Int(&secSummary, _xtPanes, nCount);
  86. if (nCount < 2)
  87. return FALSE;
  88. pPX->ExchangeSchema();
  89. TCHAR szSection[256];
  90. CXTPPaneIndexToPaneMap map;
  91. for (int i = 1; i <= nCount; i++)
  92. {
  93. wsprintf(szSection, _xtPaneSection, i);
  94. CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
  95. int nType = -1;
  96. PX_Int(&secPane, _T("Type"), nType, -1);
  97. CXTPDockingPaneBase* pPane = m_pManager->OnCreatePane((XTPDockingPaneType)nType, this);
  98. if (!pPane)
  99. {
  100. return FALSE;
  101. }
  102. pPane->m_nIndex = i;
  103. map.SetAt(i, pPane);
  104. }
  105. ASSERT(map.GetCount() == m_lstStack.GetCount());
  106. POSITION pos = m_lstStack.GetHeadPosition();
  107. while (pos)
  108. {
  109. CXTPDockingPaneBase* pPane = m_lstStack.GetNext(pos);
  110. wsprintf(szSection, _xtPaneSection, pPane->m_nIndex);
  111. CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
  112. secPane->m_dwData = (DWORD_PTR)&map;
  113. if (!pPane->DoPropExchange(&secPane))
  114. {
  115. return FALSE;
  116. }
  117. }
  118. int nIndex = 0;
  119. if (!PX_Int(&secSummary, _T("TopContainer"), nIndex))
  120. return FALSE;
  121. m_pTopContainer = (CXTPDockingPaneSplitterContainer*)map[nIndex];
  122. if (!m_pTopContainer)
  123. return FALSE;
  124. if (!PX_Int(&secSummary, _T("Client"), nIndex))
  125. return FALSE;
  126. m_pClient = (CXTPDockingPaneBase*)map[nIndex];
  127. if (!m_pClient || m_pClient->GetType() != xtpPaneTypeClient)
  128. return FALSE;
  129. return TRUE;
  130. }
  131. // The main difference between the .Net versions and the normal versions of _Save is that in the .Net
  132. // versions all the save is done is done in the exact same order of the load.
  133. void CXTPDockingPaneLayout::_Save(CXTPPropExchange* pPX)
  134. {
  135. ASSERT(!pPX->IsLoading());
  136. pPX->EmptySection();
  137. _FreeEmptyPanes();
  138. CXTPPropExchangeSection secSummary(pPX->GetSection(_xtSummary));
  139. int nCount = (int)m_lstStack.GetCount();
  140. PX_Int(&secSummary, _xtPanes, nCount);
  141. pPX->ExchangeSchema();
  142. TCHAR szSection[256];
  143. // Assign an unique value to each pane
  144. int nIndex = 1;  // important
  145. POSITION pos = m_lstPanes.GetHeadPosition();
  146. while (pos)
  147. {
  148. CXTPDockingPane* pPane = m_lstPanes.GetNext(pos);
  149. pPane->m_nIndex = nIndex++;
  150. wsprintf(szSection, _xtPaneSection, pPane->m_nIndex);
  151. CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
  152. int nType = pPane->m_type;
  153. PX_Int(&secPane, _T("Type"), nType);
  154. }
  155. pos = m_lstStack.GetHeadPosition();
  156. while (pos)
  157. {
  158. CXTPDockingPaneBase* pPane = m_lstStack.GetNext(pos);
  159. if (pPane->GetType() == xtpPaneTypeDockingPane) continue;
  160. pPane->m_nIndex = nIndex++;
  161. wsprintf(szSection, _xtPaneSection, pPane->m_nIndex);
  162. CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
  163. int nType = pPane->m_type;
  164. PX_Int(&secPane, _T("Type"), nType);
  165. }
  166. pos = m_lstPanes.GetHeadPosition();
  167. while (pos)
  168. {
  169. CXTPDockingPane* pPane = m_lstPanes.GetNext(pos);
  170. wsprintf(szSection, _xtPaneSection, pPane->m_nIndex);
  171. CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
  172. pPane->DoPropExchange(&secPane);
  173. }
  174. // Save all panes
  175. pos = m_lstStack.GetHeadPosition();
  176. while (pos)
  177. {
  178. CXTPDockingPaneBase* pPane = m_lstStack.GetNext(pos);
  179. if (pPane->GetType() == xtpPaneTypeDockingPane) continue;
  180. wsprintf(szSection, _xtPaneSection, pPane->m_nIndex);
  181. CXTPPropExchangeSection secPane(pPX->GetSection(szSection));
  182. pPane->DoPropExchange(&secPane);
  183. }
  184. PX_Int(&secSummary, _T("TopContainer"), m_pTopContainer->m_nIndex);
  185. PX_Int(&secSummary, _T("Client"), m_pClient->m_nIndex);
  186. }
  187. BOOL CXTPDockingPaneLayout::DoPropExchange(CXTPPropExchange* pPX)
  188. {
  189. if (pPX->IsLoading())
  190. return _Load(pPX);
  191. _Save(pPX);
  192. return TRUE;
  193. }
  194. BOOL CXTPDockingPaneLayout::Load(LPCTSTR strSection)
  195. {
  196. CXTPPropExchangeSection pxRoot(TRUE, _xtRootSection);
  197. CXTPPropExchangeSection pxSection(pxRoot->GetSection(strSection));
  198. return DoPropExchange(&pxSection);
  199. }
  200. void CXTPDockingPaneLayout::Save(LPCTSTR strSection)
  201. {
  202. CXTPPropExchangeSection pxRoot(FALSE, _xtRootSection);
  203. CXTPPropExchangeSection pxSection(pxRoot->GetSection(strSection));
  204. DoPropExchange(&pxSection);
  205. }
  206. void CXTPDockingPaneLayout::Serialize(CArchive& ar)
  207. {
  208. CXTPPropExchangeArchive px(ar);
  209. DoPropExchange(&px);
  210. }
  211. #ifndef _XTP_EXCLUDE_XML
  212. BOOL CXTPDockingPaneLayout::LoadFromNode(CXTPDOMNodePtr xmlNode, LPCTSTR strSection)
  213. {
  214. if (xmlNode == 0)
  215. return FALSE;
  216. CXTPPropExchangeXMLNode px(TRUE, xmlNode, strSection);
  217. return DoPropExchange(&px);
  218. }
  219. BOOL CXTPDockingPaneLayout::LoadFromFile(LPCTSTR strFileName, LPCTSTR strSection)
  220. {
  221. CXTPPropExchangeXMLNode px(TRUE, 0, _xtRootSection);
  222. if (!px.LoadFromFile(strFileName))
  223. return FALSE;
  224. CXTPPropExchangeSection pxSection(px.GetSection(strSection));
  225. if (!pxSection->OnBeforeExchange())
  226. return FALSE;
  227. return DoPropExchange(&pxSection);
  228. }
  229. void CXTPDockingPaneLayout::SaveToNode (CXTPDOMNodePtr xmlNode, LPCTSTR strSection)
  230. {
  231. if (xmlNode == 0)
  232. return;
  233. CXTPPropExchangeXMLNode px(FALSE, xmlNode, strSection);
  234. DoPropExchange(&px);
  235. }
  236. void CXTPDockingPaneLayout::SaveToFile (LPCTSTR strFileName, LPCTSTR strSection)
  237. {
  238. CXTPPropExchangeXMLNode px(FALSE, 0, _xtRootSection);
  239. CXTPPropExchangeSection pxSection(px.GetSection(strSection));
  240. DoPropExchange(&pxSection);
  241. px.SaveToFile(strFileName);
  242. }
  243. #endif
  244. BOOL CXTPDockingPaneBase::DoPropExchange(CXTPPropExchange* pPX)
  245. {
  246. PX_Long(pPX, _T("DockingCX"), m_szDocking.cx, 0);
  247. PX_Long(pPX, _T("DockingCY"), m_szDocking.cy, 0);
  248. return TRUE;
  249. }
  250. BOOL CXTPDockingPane::DoPropExchange(CXTPPropExchange* pPX)
  251. {
  252. CXTPDockingPaneBase::DoPropExchange(pPX);
  253. PX_String(pPX, _T("Title"), m_strTitle);
  254. PX_Int(pPX, _T("ID"), m_nID, 0);
  255. PX_Int(pPX, _T("IconID"), m_nIconID, -1);
  256. PX_ULong(pPX, _T("Options"), m_dwOptions, 0);
  257. int nIndex = 0;
  258. CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
  259. if (!pPX->IsLoading())
  260. {
  261. XTP_DOCKINGPANE_INFO* pInfo = m_pLayout->FindPane(this);
  262. ASSERT(pInfo);
  263. if (pInfo)
  264. {
  265. nIndex = pInfo->pDockingHolder ? pInfo->pDockingHolder->m_nIndex : 0;
  266. PX_Int(pPX, _T("DockingHolder"), nIndex, 0);
  267. nIndex = pInfo->pFloatingHolder ? pInfo->pFloatingHolder->m_nIndex : 0;
  268. PX_Int(pPX, _T("FloatingHolder"), nIndex, 0);
  269. nIndex = pInfo->pLastHolder ? pInfo->pLastHolder->m_nIndex : 0;
  270. PX_Int(pPX, _T("LastHolder"), nIndex, 0);
  271. }
  272. }
  273. else
  274. {
  275. XTP_DOCKINGPANE_INFO info (this);
  276. PX_Int(pPX, _T("DockingHolder"), nIndex, 0);
  277. if (nIndex) info.pDockingHolder = (CXTPDockingPaneBase*)(*pMap)[nIndex];
  278. PX_Int(pPX, _T("FloatingHolder"), nIndex, 0);
  279. if (nIndex) info.pFloatingHolder = (CXTPDockingPaneBase*)(*pMap)[nIndex];
  280. PX_Int(pPX, _T("LastHolder"), nIndex, 0);
  281. if (nIndex) info.pLastHolder = (CXTPDockingPaneBase*)(*pMap)[nIndex];
  282. m_pLayout->m_lstPanes.AddTail(info);
  283. }
  284. PX_Long(pPX, _T("MinTrackX"), m_ptMinTrackSize.x, 0);
  285. PX_Long(pPX, _T("MinTrackY"), m_ptMinTrackSize.y, 0);
  286. PX_Long(pPX, _T("MaxTrackX"), m_ptMaxTrackSize.x, 32000);
  287. PX_Long(pPX, _T("MaxTrackY"), m_ptMaxTrackSize.y, 32000);
  288. if (pPX->GetSchema() > _XTP_SCHEMA_97)
  289. {
  290. PX_DWord(pPX, _T("TabColor"), (DWORD&)m_clrItemTab, COLORREF_NULL);
  291. PX_Int(pPX, _T("HelpId"), m_nIDHelp, 0);
  292. DWORD dwData = (DWORD)m_dwData;
  293. PX_DWord(pPX, _T("Tag"), dwData, 0);
  294. if (pPX->IsLoading()) m_dwData = dwData;
  295. }
  296. return m_nID > 0;
  297. }
  298. BOOL CXTPDockingPaneSplitterContainer::DoPropExchange(CXTPPropExchange* pPX)
  299. {
  300. CXTPDockingPaneBase::DoPropExchange(pPX);
  301. PX_Bool(pPX, _T("Horiz"), m_bHoriz, FALSE);
  302. int nCount = 0;
  303. if (!pPX->IsLoading())
  304. {
  305. nCount = (int)m_lstPanes.GetCount();
  306. PX_Int(pPX, _xtPanes, nCount);
  307. int nIndex = 1;
  308. TCHAR szPane[256];
  309. POSITION pos = m_lstPanes.GetHeadPosition();
  310. while (pos)
  311. {
  312. CXTPDockingPaneBase* pPane = m_lstPanes.GetNext(pos);
  313. wsprintf(szPane, _xtPaneSection, nIndex++);
  314. PX_Int(pPX, szPane, pPane->m_nIndex);
  315. }
  316. }
  317. else
  318. {
  319. PX_Int(pPX, _xtPanes, nCount, 0);
  320. int nIndex = 0;
  321. TCHAR szPane[256];
  322. CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
  323. for (int i = 1; i <= nCount; i++)
  324. {
  325. wsprintf(szPane, _xtPaneSection, i);
  326. PX_Int(pPX, szPane, nIndex, 0);
  327. ASSERT(nIndex > 0);
  328. CXTPDockingPaneBase* pPane = NULL;
  329. ASSERT(pMap->Lookup(nIndex, pPane));
  330. pPane = (CXTPDockingPaneBase*)((*pMap)[nIndex]);
  331. if (!pPane) return FALSE;
  332. _InsertPane(pPane);
  333. }
  334. ASSERT(nCount > 0);
  335. }
  336. return TRUE;
  337. }
  338. BOOL CXTPDockingPaneSidePanel::DoPropExchange(CXTPPropExchange* pPX)
  339. {
  340. CXTPDockingPaneBase::DoPropExchange(pPX);
  341. int direction = m_direction;
  342. PX_Int(pPX, _T("Direction"), direction);
  343. PX_Rect(pPX, _T("WindowRect"), m_rcWindow, CRect(0, 0, 0, 0));
  344. PX_Bool(pPX, _T("Collapsed"), m_bCollapsed, FALSE);
  345. if (!pPX->IsLoading())
  346. {
  347. int nTopContainer = GetTopContainer() ? GetTopContainer()->m_nIndex : 0;
  348. PX_Int(pPX, _T("TopContaner"), nTopContainer);
  349. }
  350. else
  351. {
  352. m_direction = (XTPDockingPaneDirection)direction;
  353. int nTopContainer = 0;
  354. PX_Int(pPX, _T("TopContaner"), nTopContainer);
  355. if (nTopContainer == 0)
  356. return FALSE;
  357. CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
  358. CXTPDockingPaneBase* pTop = (CXTPDockingPaneBase*)(*pMap)[nTopContainer];
  359. if (!pTop || pTop->GetType() != xtpPaneTypeTabbedContainer)
  360. return FALSE;
  361. _InsertPane(pTop);
  362. }
  363. return TRUE;
  364. }
  365. BOOL CXTPDockingPaneAutoHidePanel::DoPropExchange(CXTPPropExchange* pPX)
  366. {
  367. CXTPDockingPaneBase::DoPropExchange(pPX);
  368. int direction = m_direction;
  369. PX_Int(pPX, _T("Direction"), direction);
  370. int nCount = 0;
  371. if (!pPX->IsLoading())
  372. {
  373. nCount = (int)m_lstPanes.GetCount();
  374. PX_Int(pPX, _xtPanes, nCount);
  375. int nIndex = 1;
  376. TCHAR szPane[256];
  377. POSITION pos = m_lstPanes.GetHeadPosition();
  378. while (pos)
  379. {
  380. CXTPDockingPaneBase* pPane = m_lstPanes.GetNext(pos);
  381. wsprintf(szPane, _xtPaneSection, nIndex++);
  382. PX_Int(pPX, szPane, pPane->m_nIndex);
  383. }
  384. }
  385. else
  386. {
  387. m_direction = (XTPDockingPaneDirection)direction;
  388. PX_Int(pPX, _xtPanes, nCount, 0);
  389. int nIndex = 0;
  390. TCHAR szPane[256];
  391. CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
  392. for (int i = 1; i <= nCount; i++)
  393. {
  394. wsprintf(szPane, _xtPaneSection, i);
  395. PX_Int(pPX, szPane, nIndex, 0);
  396. ASSERT(nIndex > 0);
  397. CXTPDockingPaneBase* pPane = NULL;
  398. ASSERT(pMap->Lookup(nIndex, pPane));
  399. pPane = (CXTPDockingPaneBase*)((*pMap)[nIndex]);
  400. if (!pPane) return FALSE;
  401. _InsertPane(pPane);
  402. }
  403. m_pLayout->m_wndPanels[m_direction] = this;
  404. }
  405. return TRUE;
  406. }
  407. BOOL CXTPDockingPaneTabbedContainer::DoPropExchange(CXTPPropExchange* pPX)
  408. {
  409. CXTPDockingPaneBase::DoPropExchange(pPX);
  410. int nCount, nSelected;
  411. if (!pPX->IsLoading())
  412. {
  413. nCount = (int)m_lstPanes.GetCount();
  414. PX_Int(pPX, _xtPanes, nCount);
  415. nSelected = m_pSelectedPane ? m_pSelectedPane->m_nIndex : 0;
  416. PX_Int(pPX, _T("Selected"), nSelected, 0);
  417. PX_Bool(pPX, _T("Maximized"), m_bMaximized, FALSE);
  418. POSITION pos = m_lstPanes.GetHeadPosition();
  419. int nIndex = 1;
  420. while (pos)
  421. {
  422. CXTPDockingPaneBase* pPane = m_lstPanes.GetNext(pos);
  423. TCHAR szPane[256];
  424. wsprintf(szPane, _xtPaneSection, nIndex++);
  425. PX_Int(pPX, szPane, pPane->m_nIndex);
  426. }
  427. }
  428. else
  429. {
  430. PX_Int(pPX, _xtPanes, nCount);
  431. PX_Int(pPX, _T("Selected"), nSelected, 0);
  432. if (pPX->GetSchema() > _XTP_SCHEMA_1122)
  433. {
  434. PX_Bool(pPX, _T("Maximized"), m_bMaximized, FALSE);
  435. }
  436. TCHAR szPane[256];
  437. CXTPDockingPane* pSelected = NULL;
  438. int nIndex = 0;
  439. CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
  440. for (int i = 1; i <= nCount; i++)
  441. {
  442. wsprintf(szPane, _xtPaneSection, i);
  443. PX_Int(pPX, szPane, nIndex, 0);
  444. ASSERT(nIndex > 0);
  445. CXTPDockingPaneBase* pPane = NULL;
  446. ASSERT(pMap->Lookup(nIndex, pPane));
  447. pPane = (CXTPDockingPaneBase*)((*pMap)[nIndex]);
  448. if (!pPane || pPane->GetType() != xtpPaneTypeDockingPane) return FALSE;
  449. _InsertPane((CXTPDockingPane*)pPane);
  450. if (nIndex == nSelected) pSelected = (CXTPDockingPane*)pPane;
  451. }
  452. if (pSelected)
  453. {
  454. SelectPane(pSelected);
  455. }
  456. }
  457. return TRUE;
  458. }
  459. BOOL CXTPDockingPaneMiniWnd::DoPropExchange(CXTPPropExchange* pPX)
  460. {
  461. CXTPDockingPaneBase::DoPropExchange(pPX);
  462. PX_Long(pPX, _T("WindowRectTopPos"), m_rcWindow.top);
  463. PX_Long(pPX, _T("WindowRectBottomPos"), m_rcWindow.bottom);
  464. PX_Long(pPX, _T("WindowRectLeftPos"), m_rcWindow.left);
  465. PX_Long(pPX, _T("WindowRectRightPos"), m_rcWindow.right);
  466. PX_Bool(pPX, _T("Collapsed"), m_bCollapsed, FALSE);
  467. PX_Int(pPX, _T("ExpandedHeight"), m_nExpandedHeight, 0);
  468. if (!pPX->IsLoading())
  469. {
  470. int nTopContainer = m_pTopContainer ? m_pTopContainer->m_nIndex : 0;
  471. PX_Int(pPX, _T("TopContaner"), nTopContainer);
  472. }
  473. else
  474. {
  475. int nTopContainer = 0;
  476. PX_Int(pPX, _T("TopContaner"), nTopContainer);
  477. if (nTopContainer == 0)
  478. return FALSE;
  479. CXTPPaneIndexToPaneMap* pMap = (CXTPPaneIndexToPaneMap*)pPX->m_dwData;
  480. CXTPDockingPaneBase* pTop = (CXTPDockingPaneBase*)(*pMap)[nTopContainer];
  481. if (!pTop || pTop->GetType() != xtpPaneTypeSplitterContainer)
  482. return FALSE;
  483. m_pTopContainer = (CXTPDockingPaneSplitterContainer*)pTop;
  484. m_pTopContainer->m_pParentContainer = this;
  485. }
  486. return TRUE;
  487. }
  488. void CXTPDockingPaneLayout::Copy(const CXTPDockingPaneLayout* pLayout)
  489. {
  490. Free();
  491. CXTPPaneToPaneMap map;
  492. // Clone them
  493. POSITION pos = pLayout->m_lstStack.GetHeadPosition();
  494. while (pos)
  495. {
  496. CXTPDockingPaneBase* pPane = pLayout->m_lstStack.GetNext(pos);
  497. if (pPane->m_pParentContainer == NULL) // hidden pane, top pane, miniwnd.
  498. {
  499. pPane->Clone(this, &map);
  500. }
  501. }
  502. ASSERT(map.GetCount() == pLayout->m_lstStack.GetCount());
  503. ASSERT(map.Lookup(pLayout->m_pClient, m_pClient));
  504. ASSERT(map.Lookup(pLayout->m_pTopContainer, (CXTPDockingPaneBase*&)m_pTopContainer));
  505. m_pClient = map[pLayout->m_pClient];
  506. m_pTopContainer = (CXTPDockingPaneSplitterContainer*)map[pLayout->m_pTopContainer];
  507. for (int i = 0; i < 4; i++)
  508. if (pLayout->m_wndPanels[i]) m_wndPanels[i] = (CXTPDockingPaneAutoHidePanel*)map[pLayout->m_wndPanels[i]];
  509. // Map Holders
  510. pos = pLayout->m_lstPanes.GetHeadPosition();
  511. while (pos)
  512. {
  513. XTP_DOCKINGPANE_INFO& info = pLayout->GetPaneList().GetNext(pos);
  514. XTP_DOCKINGPANE_INFO infoCopy;
  515. ASSERT(map.Lookup((CXTPDockingPaneBase*)info.pPane, (CXTPDockingPaneBase*&)infoCopy.pPane));
  516. infoCopy.pPane = (CXTPDockingPane*)map[(CXTPDockingPaneBase*)info.pPane];
  517. if (info.pDockingHolder) infoCopy.pDockingHolder = (CXTPDockingPaneBase*)map[info.pDockingHolder];
  518. if (info.pLastHolder) infoCopy.pLastHolder = (CXTPDockingPaneBase*)map[info.pLastHolder];
  519. if (info.pFloatingHolder) infoCopy.pFloatingHolder = (CXTPDockingPaneBase*)map[info.pFloatingHolder];
  520. m_lstPanes.AddTail(infoCopy);
  521. }
  522. }
  523. void CXTPDockingPaneLayout::_FreeEmptyPanes()
  524. {
  525. WORD w;
  526. CMapPtrToWord map;
  527. POSITION pos = m_lstPanes.GetHeadPosition();
  528. while (pos)
  529. {
  530. XTP_DOCKINGPANE_INFO& info = m_lstPanes.GetNext(pos);
  531. map.SetAt(info.pDockingHolder, TRUE);
  532. map.SetAt(info.pFloatingHolder, TRUE);
  533. map.SetAt(info.pPane->m_pParentContainer, TRUE);
  534. }
  535. BOOL bFound = TRUE;
  536. while (bFound)
  537. {
  538. bFound = FALSE;
  539. POSITION posRemove = pos = m_lstStack.GetHeadPosition();
  540. while (pos)
  541. {
  542. CXTPDockingPaneBase* pPane = m_lstStack.GetNext(pos);
  543. CXTPDockingPaneBase* pParentContainer = pPane->m_pParentContainer;
  544. switch (pPane->GetType())
  545. {
  546. case xtpPaneTypeTabbedContainer:
  547. if (!map.Lookup(pPane, w))
  548. {
  549. SAFE_CALLPTR(pParentContainer, RemovePane(pPane));
  550. m_lstStack.RemoveAt(posRemove);
  551. pPane->DeletePane();
  552. bFound = TRUE;
  553. }
  554. break;
  555. case xtpPaneTypeSplitterContainer:
  556. if (((CXTPDockingPaneSplitterContainer*)pPane)->m_lstPanes.GetCount() == 0)
  557. {
  558. SAFE_CALLPTR(pParentContainer, RemovePane(pPane));
  559. m_lstStack.RemoveAt(posRemove);
  560. pPane->DeletePane();
  561. bFound = TRUE;
  562. }
  563. else if (pParentContainer && (pParentContainer->GetType() == xtpPaneTypeSplitterContainer)
  564. && (((CXTPDockingPaneSplitterContainer*)pPane)->m_lstPanes.GetCount() == 1)
  565. && (((CXTPDockingPaneSplitterContainer*)pParentContainer)->m_lstPanes.GetCount() == 1))
  566. {
  567. CXTPDockingPaneBase* pChildPane = ((CXTPDockingPaneSplitterContainer*)pPane)->m_lstPanes.RemoveHead();
  568. ((CXTPDockingPaneSplitterContainer*)pParentContainer)->m_lstPanes.RemoveHead();
  569. ((CXTPDockingPaneSplitterContainer*)pParentContainer)->m_lstPanes.AddHead(pChildPane);
  570. pChildPane->m_pParentContainer = pParentContainer;
  571. m_lstStack.RemoveAt(posRemove);
  572. pPane->DeletePane();
  573. bFound = TRUE;
  574. }
  575. break;
  576. case xtpPaneTypeMiniWnd:
  577. if (((CXTPDockingPaneMiniWnd*)pPane)->m_pTopContainer == NULL)
  578. {
  579. m_lstStack.RemoveAt(posRemove);
  580. pPane->DeletePane();
  581. bFound = TRUE;
  582. }
  583. break;
  584. case xtpPaneTypeSidePanel:
  585. if (((CXTPDockingPaneSidePanel*)pPane)->m_lstPanes.GetCount() == 0)
  586. {
  587. m_lstStack.RemoveAt(posRemove);
  588. pPane->DeletePane();
  589. bFound = TRUE;
  590. }
  591. break;
  592. }
  593. posRemove = pos;
  594. }
  595. }
  596. }
  597. XTP_DOCKINGPANE_INFO* CXTPDockingPaneLayout::FindPane(CXTPDockingPane* pPane)
  598. {
  599. POSITION pos = m_lstPanes.GetHeadPosition();
  600. while (pos)
  601. {
  602. XTP_DOCKINGPANE_INFO& info = m_lstPanes.GetNext(pos);
  603. if (info.pPane == pPane)
  604. return &info;
  605. }
  606. return 0;
  607. }
  608. XTPDockingPaneDirection CXTPDockingPaneLayout::_GetPaneDirection(const CXTPDockingPaneBase* pPane) const
  609. {
  610. if (pPane->GetType() == xtpPaneTypeMiniWnd)
  611. return (XTPDockingPaneDirection)4;
  612. if (!pPane->m_pParentContainer || pPane->GetType() == xtpPaneTypeClient)
  613. return (XTPDockingPaneDirection)-1;
  614. if (pPane->m_pParentContainer->GetType() == xtpPaneTypeAutoHidePanel)
  615. {
  616. return ((CXTPDockingPaneAutoHidePanel*)pPane->m_pParentContainer)->m_direction;
  617. }
  618. if (pPane->GetType() == xtpPaneTypeSidePanel)
  619. {
  620. return ((CXTPDockingPaneSidePanel*)pPane)->m_direction;
  621. }
  622. if (pPane->m_pParentContainer->GetType() == xtpPaneTypeSplitterContainer)
  623. {
  624. POSITION pos = pPane->m_pParentContainer->ContainPane(m_pClient);
  625. if (pos)
  626. {
  627. CXTPDockingPaneSplitterContainer* pSplitter = (CXTPDockingPaneSplitterContainer*)pPane->m_pParentContainer;
  628. if (pSplitter->_Before(pPane, pos))
  629. {
  630. return  pSplitter->IsHoriz() ? xtpPaneDockLeft : xtpPaneDockTop;
  631. }
  632. else
  633. {
  634. return  pSplitter->IsHoriz() ? xtpPaneDockRight : xtpPaneDockBottom;
  635. }
  636. }
  637. }
  638. return _GetPaneDirection(pPane->m_pParentContainer);
  639. }
  640. void CXTPDockingPaneLayout::_AddPanesTo(CXTPDockingPaneTabbedContainer* pContainer, CXTPDockingPaneBaseList& lst, DWORD dwIgnoredOptions)
  641. {
  642. POSITION pos = lst.GetHeadPosition();
  643. while (pos)
  644. {
  645. CXTPDockingPane* pPane = (CXTPDockingPane*)lst.GetNext(pos);
  646. if ((((CXTPDockingPane*)pPane)->GetOptions() & dwIgnoredOptions) == 0)
  647. {
  648. SAFE_CALLPTR(pPane->m_pParentContainer, RemovePane(pPane));
  649. pContainer->_InsertPane(pPane);
  650. }
  651. }
  652. }
  653. BOOL CXTPDockingPaneLayout::_FindTabbedPaneToHide(CXTPDockingPaneAutoHidePanel* pPanel, CXTPDockingPaneBase* pPane)
  654. {
  655. CXTPDockingPaneBaseList lst;
  656. pPane->FindPane(xtpPaneTypeDockingPane, &lst);
  657. if (lst.IsEmpty())
  658. return FALSE;
  659. CXTPDockingPane* pPanePrimary = (CXTPDockingPane*)lst.GetHead();
  660. XTP_DOCKINGPANE_INFO* pInfo = FindPane(pPanePrimary);
  661. if (!pInfo || pInfo->pDockingHolder == NULL)
  662. return FALSE;
  663. POSITION pos = pPanel->m_lstPanes.GetHeadPosition();
  664. while (pos)
  665. {
  666. CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)pPanel->m_lstPanes.GetNext(pos);
  667. CXTPDockingPane* pContainerPane = (CXTPDockingPane*)pContainer->GetFirstPane();
  668. if (pContainerPane)
  669. {
  670. XTP_DOCKINGPANE_INFO* pContanerPaneInfo = FindPane(pContainerPane);
  671. if (pContanerPaneInfo && pContanerPaneInfo->pDockingHolder == pInfo->pDockingHolder)
  672. {
  673. _AddPanesTo(pContainer, lst, xtpPaneNoHideable);
  674. return TRUE;
  675. }
  676. }
  677. }
  678. return FALSE;
  679. }
  680. void CXTPDockingPaneLayout::HidePane(CXTPDockingPaneBase* pPane)
  681. {
  682. ASSERT(!m_bUserLayout);
  683. XTPDockingPaneDirection direction = _GetPaneDirection(pPane);
  684. if (direction < 0 || direction >= 4)
  685. direction = xtpPaneDockLeft;
  686. if (m_wndPanels[direction] == 0)
  687. {
  688. m_wndPanels[direction] = (CXTPDockingPaneAutoHidePanel*)m_pManager->
  689. OnCreatePane(xtpPaneTypeAutoHidePanel, this);
  690. m_wndPanels[direction]->m_direction = direction;
  691. }
  692. if (_FindTabbedPaneToHide(m_wndPanels[direction], pPane))
  693. return;
  694. if (pPane->GetType() == xtpPaneTypeDockingPane)
  695. {
  696. pPane->m_pParentContainer->RemovePane(pPane);
  697. CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)m_pManager->
  698. OnCreatePane(xtpPaneTypeTabbedContainer, this);
  699. pContainer->Init((CXTPDockingPane*)pPane, m_pManager->GetSite());
  700. pPane = pContainer;
  701. }
  702. else if (pPane->GetType() == xtpPaneTypeTabbedContainer)
  703. {
  704. pPane = ((CXTPDockingPaneBase*)pPane)->Clone(this, 0, xtpPaneNoHideable);
  705. }
  706. m_wndPanels[direction]->_InsertPane(pPane);
  707. }
  708. void CXTPDockingPaneLayout::RepositionMargins(CRect& rect, const CRect& rcClientMargins)
  709. {
  710. int i;
  711. if (rcClientMargins.IsRectNull())
  712. {
  713. for (i = 0; i < 4; i++)
  714. {
  715. SAFE_DELETE(m_wndMargins[i]);
  716. }
  717. return;
  718. }
  719. for (i = 0; i < 4; i++)
  720. {
  721. if (m_wndMargins[i] == 0)
  722. {
  723. m_wndMargins[i] = new CXTPDockingPaneSplitterWnd();
  724. m_wndMargins[i]->Create(m_pManager, i == xtpPaneDockTop || i == xtpPaneDockBottom);
  725. }
  726. }
  727. CRect rcClient(rect);
  728. rcClient.DeflateRect(rcClientMargins);
  729. m_wndMargins[xtpPaneDockLeft]->MoveWindow(CRect(rect.left, rect.top, rcClient.left, rect.bottom));
  730. m_wndMargins[xtpPaneDockRight]->MoveWindow(CRect(rcClient.right , rect.top, rect.right, rect.bottom));
  731. m_wndMargins[xtpPaneDockTop]->MoveWindow(CRect(rcClient.left, rect.top, rcClient.right, rcClient.top));
  732. m_wndMargins[xtpPaneDockBottom]->MoveWindow(CRect(rcClient.left, rcClient.bottom, rcClient.right, rect.bottom));
  733. for (i = 0; i < 4; i++)
  734. {
  735. m_wndMargins[i]->Invalidate(FALSE);
  736. }
  737. rect = rcClient;
  738. }
  739. void CXTPDockingPaneLayout::OnSizeParent(CWnd* pParent, CRect rect, LPVOID lParam)
  740. {
  741. AFX_SIZEPARENTPARAMS* lpLayout = (AFX_SIZEPARENTPARAMS*)lParam;
  742. for (int i = 0; i < 4; i++)
  743. {
  744. SAFE_CALLPTR(m_wndPanels[i], OnSizeParentEx(pParent, rect, lParam));
  745. }
  746. int nMargin = m_pManager->GetClientMargin();
  747. CRect rcClientMargins(nMargin, nMargin, nMargin, nMargin);
  748. if (lpLayout->hDWP != NULL)
  749. {
  750. RepositionMargins(rect, rcClientMargins);
  751. }
  752. else
  753. {
  754. rect.DeflateRect(rcClientMargins);
  755. }
  756. m_pClient->OnSizeParent(pParent, rect, lParam);
  757. m_pTopContainer->OnSizeParent(pParent, rect, lParam);
  758. if (lpLayout->hDWP)
  759. {
  760. CXTPDockingPaneSidePanel::OnSizeParentEx(m_pManager, pParent, lpLayout->rect);
  761. }
  762. }
  763. void CXTPDockingPaneLayout::DestroyPane(CXTPDockingPane* pPane)
  764. {
  765. if (pPane == NULL) return;
  766. SAFE_CALLPTR(pPane->m_pParentContainer, RemovePane(pPane));
  767. POSITION pos = m_lstPanes.GetHeadPosition();
  768. while (pos)
  769. {
  770. if (m_lstPanes.GetAt(pos) == pPane)
  771. {
  772. m_lstPanes.RemoveAt(pos);
  773. break;
  774. }
  775. m_lstPanes.GetNext(pos);
  776. }
  777. pos = m_lstStack.GetHeadPosition();
  778. while (pos)
  779. {
  780. if (m_lstStack.GetAt(pos) == pPane)
  781. {
  782. m_lstStack.RemoveAt(pos);
  783. break;
  784. }
  785. m_lstStack.GetNext(pos);
  786. }
  787. ((CXTPDockingPane*)pPane)->InternalRelease();
  788. _FreeEmptyPanes();
  789. }
  790. void CXTPDockingPaneLayout::MoveToTail(CXTPDockingPaneBase* pPane)
  791. {
  792. POSITION pos = m_lstStack.GetHeadPosition();
  793. while (pos)
  794. {
  795. if (m_lstStack.GetAt(pos) == pPane)
  796. {
  797. m_lstStack.RemoveAt(pos);
  798. m_lstStack.AddTail(pPane);
  799. return;
  800. }
  801. m_lstStack.GetNext(pos);
  802. }
  803. }