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

对话框与窗口

开发平台:

Visual C++

  1. // XTPDockingPaneSidePanel.cpp : implementation of the CXTPDockingPaneSidePanel 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 "Resource.h"
  22. #include "Common/XTPVC80Helpers.h"
  23. #include "Common/XTPDrawHelpers.h"
  24. #include "Common/XTPColorManager.h"
  25. #include "Common/XTPImageManager.h"
  26. #include "Common/XTPResourceManager.h"
  27. #include "Common/XTPToolTipContext.h"
  28. #include "TabManager/XTPTabManager.h"
  29. #include "XTPDockingPane.h"
  30. #include "XTPDockingPaneManager.h"
  31. #include "XTPDockingPaneTabbedContainer.h"
  32. #include "XTPDockingPaneSidePanel.h"
  33. #include "XTPDockingPaneLayout.h"
  34. #include "XTPDockingPaneContext.h"
  35. #include "XTPDockingPaneAutoHidePanel.h"
  36. #ifdef _DEBUG
  37. #define new DEBUG_NEW
  38. #undef THIS_FILE
  39. static char THIS_FILE[] = __FILE__;
  40. #endif
  41. #define TID_CHECKACTIVE 1
  42. #define TID_SLIDEIN 2
  43. #define TID_SLIDEOUT 3
  44. AFX_INLINE int ResetStepsCount()
  45. {
  46. if (CXTPDockingPaneAutoHideWnd::m_nAnimationInterval == 0)
  47. return 1;
  48. return max(1, CXTPDockingPaneAutoHideWnd::m_nAnimationDuration / CXTPDockingPaneAutoHideWnd::m_nAnimationInterval);
  49. }
  50. CXTPDockingPaneSidePanel::CXTPDockingPaneSidePanel(CXTPDockingPaneLayout* pLayout)
  51. : CXTPDockingPaneBaseContainer(xtpPaneTypeSidePanel, pLayout)
  52. {
  53. m_direction = xtpPaneDockLeft;
  54. m_bActive = FALSE;
  55. m_pCaptionButtons = new CXTPDockingPaneCaptionButtons();
  56. m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_CLOSE, this));
  57. m_pCaptionButtons->Add(new CXTPDockingPaneCaptionButton(XTP_IDS_DOCKINGPANE_AUTOHIDE, this));
  58. m_bSlideOut = m_bExpanded = m_bCollapsed = FALSE;
  59. m_nSlideStep = 0;
  60. m_nStepsCount = ResetStepsCount();
  61. m_nDeactivationCount = 0;
  62. }
  63. CXTPDockingPaneSidePanel::~CXTPDockingPaneSidePanel()
  64. {
  65. }
  66. void CXTPDockingPaneSidePanel::DeletePane()
  67. {
  68. InternalRelease();
  69. }
  70. void CXTPDockingPaneSidePanel::OnFinalRelease()
  71. {
  72. if (m_hWnd != NULL)
  73. DestroyWindow();
  74. CCmdTarget::OnFinalRelease();
  75. }
  76. BOOL CXTPDockingPaneSidePanel::Init(CXTPDockingPaneBase* pBasePane, XTPDockingPaneDirection direction, CRect rc)
  77. {
  78. CXTPDockingPaneBaseList lstPanes;
  79. pBasePane->FindPane(xtpPaneTypeDockingPane, &lstPanes);
  80. if (lstPanes.GetCount() == 0)
  81. return FALSE;
  82. m_direction = direction;
  83. m_rcWindow = rc;
  84. CreateContainer();
  85. CXTPDockingPaneTabbedContainer* pContainer = (CXTPDockingPaneTabbedContainer*)GetDockingPaneManager()->
  86. OnCreatePane(xtpPaneTypeTabbedContainer, m_pLayout);
  87. BOOL bInit = FALSE;
  88. POSITION pos = lstPanes.GetHeadPosition();
  89. while (pos)
  90. {
  91. CXTPDockingPane* pPane = (CXTPDockingPane*)lstPanes.GetNext(pos);
  92. if (pPane->GetContainer())
  93. {
  94. pPane->GetContainer()->RemovePane(pPane);
  95. }
  96. if (!bInit)
  97. {
  98. pContainer->Init((CXTPDockingPane*)pPane, this);
  99. }
  100. else
  101. {
  102. pContainer->_InsertPane(pPane, FALSE);
  103. }
  104. bInit = TRUE;
  105. }
  106. _InsertPane(pContainer);
  107. OnFocusChanged();
  108. m_nIdleFlags = 0;
  109. return TRUE;
  110. }
  111. void CXTPDockingPaneSidePanel::CreateContainer()
  112. {
  113. m_bInRecalcLayout = TRUE;
  114. if (!m_hWnd)
  115. {
  116. VERIFY(Create(m_rcWindow));
  117. }
  118. m_bInRecalcLayout = FALSE;
  119. }
  120. BOOL CXTPDockingPaneSidePanel::Create(CRect rc)
  121. {
  122. if (m_hWnd)
  123. return TRUE;
  124. if (!CreateEx(0, _T("XTPDockingPaneSidePanel"), _T(""), WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD, rc, GetDockingPaneManager()->GetSite(), 0))
  125. {
  126. return FALSE;
  127. }
  128. m_pCaptionButtons->CheckForMouseOver(CPoint(-1, -1));
  129. return TRUE;
  130. }
  131. void CXTPDockingPaneSidePanel::PostNcDestroy()
  132. {
  133. // prevent auto deleting
  134. }
  135. void CXTPDockingPaneSidePanel::RecalcLayout(BOOL /*bNotify*/)
  136. {
  137. if (m_bInRecalcLayout)
  138. return;
  139. m_bInRecalcLayout = TRUE;
  140. CXTPDockingPaneManager* pManager = GetDockingPaneManager();
  141. CWnd* pSite = GetDockingSite();
  142. CRect rcClient = pManager->GetClientPane()->GetPaneWindowRect();
  143. pSite->ScreenToClient(rcClient);
  144. OnSizeParentEx(pManager, pSite, rcClient);
  145. m_bInRecalcLayout = FALSE;
  146. }
  147. void CXTPDockingPaneSidePanel::OnFocusChanged()
  148. {
  149. CXTPDockingPaneTabbedContainer* pContainer = GetTopContainer();
  150. if (pContainer)
  151. {
  152. pContainer->OnFocusChanged();
  153. BOOL bActive = pContainer->IsActive();
  154. if (bActive != m_bActive)
  155. {
  156. m_bActive = bActive;
  157. InvalidatePane(FALSE);
  158. }
  159. }
  160. }
  161. void CXTPDockingPaneSidePanel::InvalidatePane(BOOL /*bSelectionChanged*/)
  162. {
  163. if (m_hWnd)
  164. {
  165. Invalidate(FALSE);
  166. }
  167. }
  168. CXTPDockingPaneTabbedContainer* CXTPDockingPaneSidePanel::GetTopContainer() const
  169. {
  170. return (CXTPDockingPaneTabbedContainer*)GetFirstPane();
  171. }
  172. void CXTPDockingPaneSidePanel::OnChildContainerChanged(CXTPDockingPaneBase* /*pContainer*/)
  173. {
  174. if (!m_hWnd)
  175. return;
  176. m_bExpanded = FALSE;
  177. m_nSlideStep = 0;
  178. if (IsEmpty())
  179. {
  180. DestroyWindow();
  181. }
  182. else
  183. {
  184. PostMessage(WM_IDLEUPDATECMDUI);
  185. }
  186. GetDockingPaneManager()->RecalcFrameLayout(NULL, TRUE);
  187. }
  188. void CXTPDockingPaneSidePanel::RemovePane(CXTPDockingPaneBase* pPane)
  189. {
  190. POSITION pos = m_lstPanes.Find(pPane);
  191. ASSERT(pos);
  192. m_lstPanes.RemoveAt(pos);
  193. if (IsEmpty())
  194. {
  195. DestroyWindow();
  196. }
  197. pPane->m_pParentContainer = NULL;
  198. }
  199. struct CXTPDockingPaneSidePanel::LENGTH
  200. {
  201. int nPos;
  202. int nSize;
  203. int nIndex;
  204. int nHeight;
  205. CXTPDockingPaneSidePanel* pPanel;
  206. int StartPos() {
  207. return nPos;
  208. }
  209. int EndPos() {
  210. return nPos + nSize;
  211. }
  212. };
  213. int _cdecl CXTPDockingPaneSidePanel::CompareLength(const void *arg1, const void *arg2)
  214. {
  215. int& dOffset1 = ((LENGTH*)arg1)->nPos;
  216. int& dOffset2 = ((LENGTH*)arg2)->nPos;
  217. return dOffset1 - dOffset2;
  218. }
  219. void CXTPDockingPaneSidePanel::SortLength(LENGTH* pLength, int nFirstIndex, int nLastIndex)
  220. {
  221. if (nLastIndex - nFirstIndex < 1)
  222. return;
  223. qsort(pLength + nFirstIndex, nLastIndex - nFirstIndex + 1, sizeof(LENGTH), CompareLength);
  224. for (int i = nFirstIndex; i <= nLastIndex; i++)
  225. {
  226. CXTPDockingPaneSidePanel* pPanel = pLength[i].pPanel;
  227. pPanel->m_nLengthIndex = i;
  228. }
  229. }
  230. void CXTPDockingPaneSidePanel::MovePanel(XTPDockingPaneDirection direction, CRect rect)
  231. {
  232. m_direction = direction;
  233. m_rcWindow = rect;
  234. m_pLayout->MoveToTail(this);
  235. RecalcLayout(FALSE);
  236. InvalidatePane(FALSE);
  237. }
  238. void CXTPDockingPaneSidePanel::MovePanel(LENGTH* pLength, CRect rect)
  239. {
  240. m_bInRecalcLayout = TRUE;
  241. if (m_bCollapsed && m_bSlideOut)
  242. {
  243. m_bSlideOut = FALSE;
  244. m_bExpanded = FALSE;
  245. m_nSlideStep = 0;
  246. KillTimer(TID_SLIDEOUT);
  247. OnAction(xtpPaneActionCollapsed);
  248. }
  249. BOOL bHorizontal = IsHorizontal();
  250. CSize sz = bHorizontal ? CSize(pLength->nSize, pLength->nHeight) : CSize(pLength->nHeight, pLength->nSize);
  251. int nMinHeight = GetMinHeight();
  252. if (m_bCollapsed && !m_bExpanded)
  253. {
  254. if (bHorizontal) sz.cy = nMinHeight; else sz.cx = nMinHeight;
  255. }
  256. else
  257. {
  258. if (bHorizontal) sz.cy = max(sz.cy, nMinHeight); else sz.cx = max(sz.cx, nMinHeight);
  259. }
  260. CPoint pt;
  261. switch (m_direction)
  262. {
  263. case xtpPaneDockLeft: pt = CPoint(rect.left, pLength->nPos + rect.top); break;
  264. case xtpPaneDockTop: pt = CPoint(rect.left + pLength->nPos, rect.top); break;
  265. case xtpPaneDockRight: pt = CPoint(rect.right - sz.cx, rect.top + pLength->nPos); break;
  266. case xtpPaneDockBottom: pt = CPoint(rect.left + pLength->nPos, rect.bottom - sz.cy); break;
  267. }
  268. SetWindowPos(&CWnd::wndTop, pt.x, pt.y, sz.cx, sz.cy, SWP_NOOWNERZORDER | SWP_SHOWWINDOW);
  269. CRect rcClient;
  270. GetClientRect(rcClient);
  271. GetPaintManager()->AdjustClientRect(this, rcClient);
  272. CXTPDockingPaneTabbedContainer* pContainer = GetTopContainer();
  273. if (pContainer)
  274. {
  275. pContainer->OnSizeParent(this, rcClient, NULL);
  276. }
  277. m_bInRecalcLayout = FALSE;
  278. }
  279. void CXTPDockingPaneSidePanel::OnSizeParentEx(CSidePanelArray& arrSide, CWnd* /*pParent*/, CRect rect)
  280. {
  281. XTPDockingPaneDirection direction = arrSide[0]->m_direction;
  282. BOOL bHorizontal = direction == xtpPaneDockTop || direction == xtpPaneDockBottom;
  283. int nCount = (int)arrSide.GetSize(), i, j;
  284. LENGTH* pLength = new LENGTH[nCount];
  285. for (i = 0; i < nCount; i++)
  286. {
  287. CXTPDockingPaneSidePanel* pPanel = arrSide[i];
  288. CRect rcPanel(pPanel->m_rcWindow);
  289. MINMAXINFO mmi;
  290. pPanel->GetMinMaxInfo(&mmi);
  291. if (rcPanel.Height() > mmi.ptMaxTrackSize.y) rcPanel.bottom = rcPanel.top + mmi.ptMaxTrackSize.y;
  292. if (rcPanel.Height() < mmi.ptMinTrackSize.y) rcPanel.bottom = rcPanel.top + mmi.ptMinTrackSize.y;
  293. if (rcPanel.Width() > mmi.ptMaxTrackSize.x) rcPanel.right = rcPanel.left + mmi.ptMaxTrackSize.x;
  294. if (rcPanel.Width() < mmi.ptMinTrackSize.x) rcPanel.right = rcPanel.left + mmi.ptMinTrackSize.x;
  295. pLength[i].nSize = bHorizontal ? rcPanel.Width() : rcPanel.Height();
  296. pLength[i].nPos = bHorizontal ? rcPanel.left : rcPanel.top;
  297. pLength[i].nIndex = i;
  298. pLength[i].pPanel = pPanel;
  299. pLength[i].nHeight = bHorizontal ? min(rect.Height(), rcPanel.Height()) : min(rect.Width(), rcPanel.Width());
  300. }
  301. SortLength(pLength, 0, nCount - 1);
  302. for (i = 1; i < nCount; i++)
  303. {
  304. int nLengthIndex = arrSide[i]->m_nLengthIndex;
  305. int nLeft = pLength[nLengthIndex].StartPos();
  306. int nRight = pLength[nLengthIndex].EndPos();
  307. for (j = nLengthIndex - 1; j >= 0; j--)
  308. {
  309. if (pLength[j].EndPos() > nLeft)
  310. {
  311. if (pLength[j].nIndex < i)
  312. {
  313. pLength[j].nPos = nLeft - pLength[j].nSize;
  314. nLeft = pLength[j].StartPos();
  315. }
  316. }
  317. else break;
  318. }
  319. SortLength(pLength, j + 1, nLengthIndex - 1);
  320. for (j = nLengthIndex + 1; j < nCount; j++)
  321. {
  322. if (pLength[j].StartPos() < nRight)
  323. {
  324. if (pLength[j].nIndex < i)
  325. {
  326. pLength[j].nPos = nRight;
  327. nRight = pLength[j].EndPos();
  328. }
  329. }
  330. else break;
  331. }
  332. SortLength(pLength, nLengthIndex + 1, j - 1);
  333. }
  334. int nBegin = 0;
  335. int nEnd = bHorizontal ? rect.Width() : rect.Height();
  336. int nRight = nEnd;
  337. int nLeft = nBegin;
  338. for (i = nCount - 1; i >= 0; i--)
  339. {
  340. if (pLength[i].EndPos() > nRight)
  341. {
  342. pLength[i].nPos = nRight - pLength[i].nSize;
  343. nRight = pLength[i].StartPos();
  344. }
  345. else break;
  346. }
  347. for (i = 0; i < nCount; i++)
  348. {
  349. if (pLength[i].StartPos() < nLeft)
  350. {
  351. pLength[i].nPos = nLeft;
  352. nLeft = pLength[i].EndPos();
  353. }
  354. else break;
  355. }
  356. int nTotal = pLength[nCount - 1].EndPos();
  357. int cxExtra = nTotal - nEnd;
  358. if (cxExtra > 0)
  359. {
  360. nLeft = 0;
  361. for (i = 0; i < nCount; i++)
  362. {
  363. pLength[i].nPos = nLeft;
  364. int cxAddExtra = nTotal == 0 ? cxExtra / nCount : cxExtra * pLength[i].nSize / nTotal;
  365. nTotal -= pLength[i].nSize;
  366. pLength[i].nSize -= cxAddExtra;
  367. cxExtra -= cxAddExtra;
  368. nLeft = pLength[i].EndPos();
  369. }
  370. }
  371. for (i = 0; i < nCount; i++)
  372. {
  373. int nIndex = pLength[i].nIndex;
  374. CXTPDockingPaneSidePanel* pPanel = arrSide[nIndex];
  375. pPanel->MovePanel(&pLength[i], rect);
  376. }
  377. delete[] pLength;
  378. }
  379. void CXTPDockingPaneSidePanel::OnSizeParentEx(CXTPDockingPaneManager* pManager, CWnd* pParent, CRect rect)
  380. {
  381. rect.DeflateRect(pManager->GetSideDockingMargin());
  382. CXTPDockingPaneBaseList& list = pManager->GetPaneStack();
  383. CSidePanelArray arrPanels[4];
  384. POSITION pos = list.GetHeadPosition();
  385. while (pos)
  386. {
  387. CXTPDockingPaneBase* pPane = list.GetNext(pos);
  388. if (pPane->GetType() == xtpPaneTypeSidePanel)
  389. {
  390. CXTPDockingPaneSidePanel* pPanel = (CXTPDockingPaneSidePanel*)pPane;
  391. if (!pPanel->IsEmpty())
  392. {
  393. arrPanels[pPanel->m_direction].Add(pPanel);
  394. }
  395. }
  396. }
  397. for (int i = 0; i < 4; i++)
  398. {
  399. if (arrPanels[i].GetSize() > 0)
  400. {
  401. OnSizeParentEx(arrPanels[i], pParent, rect);
  402. }
  403. }
  404. }
  405. void CXTPDockingPaneSidePanel::_InsertPane(CXTPDockingPaneBase* pPane)
  406. {
  407. ASSERT(m_lstPanes.IsEmpty());
  408. ASSERT(pPane->GetType() == xtpPaneTypeTabbedContainer);
  409. if (!m_hWnd && !m_pLayout->IsUserLayout() && pPane->GetPaneHwnd())
  410. {
  411. CreateContainer();
  412. }
  413. m_lstPanes.AddTail(pPane);
  414. pPane->SetParentContainer(this);
  415. pPane->SetDockingSite(this);
  416. pPane->OnParentContainerChanged(this);
  417. ((CXTPDockingPaneTabbedContainer*)pPane)->ShowTitle(FALSE);
  418. }
  419. void CXTPDockingPaneSidePanel::Copy(CXTPDockingPaneBase* pCloneBase, CXTPPaneToPaneMap* pMap, DWORD /*dwIgnoredOptions*/)
  420. {
  421. CXTPDockingPaneSidePanel* pClone = (CXTPDockingPaneSidePanel*)pCloneBase;
  422. ASSERT(pClone);
  423. if (!pClone)
  424. return;
  425. m_direction = pClone->m_direction;
  426. m_rcWindow = pClone->m_rcWindow;
  427. m_bCollapsed = pClone->m_bCollapsed;
  428. m_pDockingSite = GetDockingPaneManager()->GetSite();
  429. CXTPDockingPaneTabbedContainer* pContainer = pClone->GetTopContainer();
  430. if (pContainer)
  431. {
  432. _InsertPane(pContainer->Clone(m_pLayout, pMap));
  433. }
  434. }
  435. CString CXTPDockingPaneSidePanel::GetTitle() const
  436. {
  437. CXTPDockingPaneTabbedContainer* pContainer = GetTopContainer();
  438. if (!pContainer)
  439. return _T("");
  440. return pContainer->GetTitle();
  441. }
  442. BEGIN_MESSAGE_MAP(CXTPDockingPaneSidePanel, CMiniFrameWnd)
  443. ON_WM_PAINT()
  444. ON_WM_LBUTTONDOWN()
  445. ON_WM_TIMER()
  446. ON_WM_LBUTTONDBLCLK()
  447. ON_WM_RBUTTONUP()
  448. ON_WM_SIZE()
  449. ON_WM_MOUSEMOVE()
  450. ON_MESSAGE_VOID(WM_MOUSELEAVE, OnMouseLeave)
  451. ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
  452. ON_WM_NCHITTEST_EX()
  453. ON_WM_NCLBUTTONDOWN()
  454. END_MESSAGE_MAP()
  455. void CXTPDockingPaneSidePanel::OnPaint()
  456. {
  457. CPaintDC dcPaint(this);
  458. CXTPClientRect rc(this);
  459. CXTPBufferDC dc(dcPaint);
  460. GetPaintManager()->DrawSidePanel(&dc, this, rc);
  461. }
  462. void CXTPDockingPaneSidePanel::OnSize(UINT nType, int cx, int cy)
  463. {
  464. CMiniFrameWnd::OnSize(nType, cx, cy);
  465. Invalidate(FALSE);
  466. }
  467. CXTPDockingPaneCaptionButton* CXTPDockingPaneSidePanel::HitTestCaptionButton(CPoint point) const
  468. {
  469. for (int i = 0; i < m_pCaptionButtons->GetSize(); i++)
  470. {
  471. CXTPDockingPaneCaptionButton* pButton = m_pCaptionButtons->GetAt(i);
  472. if (pButton->PtInRect(point))
  473. return pButton->IsEnabled() ? pButton : NULL;
  474. }
  475. return NULL;
  476. }
  477. void CXTPDockingPaneSidePanel::OnCaptionButtonClick(CXTPDockingPaneCaptionButton* pButton)
  478. {
  479. CXTPDockingPaneManager* pManager = GetDockingPaneManager();
  480. switch (pButton->GetID())
  481. {
  482. case XTP_IDS_DOCKINGPANE_CLOSE:
  483. {
  484. CXTPDockingPaneBaseList lstPanes;
  485. FindPane(xtpPaneTypeDockingPane, &lstPanes);
  486. POSITION pos = lstPanes.GetTailPosition();
  487. while (pos)
  488. {
  489. CXTPDockingPane* pPane = (CXTPDockingPane*)lstPanes.GetPrev(pos);
  490. if ((pPane->GetOptions() & xtpPaneNoCloseable) != 0)
  491. continue;
  492. pPane->InternalAddRef();
  493. if (!pManager->NotifyAction(xtpPaneActionClosing, pPane))
  494. {
  495. pPane->Close();
  496. pManager->NotifyAction(xtpPaneActionClosed, pPane);
  497. }
  498. pPane->InternalRelease();
  499. }
  500. }
  501. break;
  502. case XTP_IDS_DOCKINGPANE_AUTOHIDE:
  503. OnPinButtonClick();
  504. break;
  505. }
  506. }
  507. CXTPDockingPane* CXTPDockingPaneSidePanel::GetSelectedPane() const
  508. {
  509. if (GetTopContainer())
  510. return GetTopContainer()->GetSelected();
  511. return NULL;
  512. }
  513. BOOL CXTPDockingPaneSidePanel::IsCaptionButtonVisible(CXTPDockingPaneCaptionButton* pButton)
  514. {
  515. CXTPDockingPane* pSelectedPane = GetSelectedPane();
  516. if (pButton->GetID() == XTP_IDS_DOCKINGPANE_CLOSE)
  517. return pSelectedPane && ((pSelectedPane->GetOptions() & xtpPaneNoCloseable) == 0);
  518. if (pButton->GetID() == XTP_IDS_DOCKINGPANE_AUTOHIDE)
  519. {
  520. pButton->SetState(m_bCollapsed ? xtpPanePinPushed : 0);
  521. return pSelectedPane && ((pSelectedPane->GetOptions() & xtpPaneNoHideable) == 0);
  522. }
  523. return TRUE;
  524. }
  525. void CXTPDockingPaneSidePanel::_RestoreFocus()
  526. {
  527. CXTPDockingPaneTabbedContainer* pContainer = GetTopContainer();
  528. if (pContainer) pContainer->_RestoreFocus();
  529. }
  530. void CXTPDockingPaneSidePanel::OnCaptionLButtonDown(CPoint point)
  531. {
  532. if (GetKeyState(VK_LBUTTON) < 0)
  533. {
  534. if (OnAction(xtpPaneActionDragging))
  535. return;
  536. CXTPDockingPaneContext* pContext = GetDockingPaneManager()->GetDockingContext();
  537. CRect rcWindow;
  538. GetWindowRect(rcWindow);
  539. pContext->Drag(GetTopContainer(), point, rcWindow);
  540. }
  541. }
  542. void CXTPDockingPaneSidePanel::OnLButtonDown(UINT /*nFlags*/, CPoint point)
  543. {
  544. if (m_bCollapsed && !m_bExpanded)
  545. {
  546. Expand();
  547. GetCursorPos(&point);
  548. ScreenToClient(&point);
  549. InvalidatePane(FALSE);
  550. UpdateWindow();
  551. }
  552. _RestoreFocus();
  553. CXTPDockingPaneCaptionButton* pButton = HitTestCaptionButton(point);
  554. if (pButton)
  555. {
  556. if (pButton->Click(this, point))
  557. {
  558. OnCaptionButtonClick(pButton);
  559. }
  560. return;
  561. }
  562. CRect rcCaption = GetPaintManager()->GetPaneCaptionRect(this);
  563. if (rcCaption.PtInRect(point))
  564. {
  565. ClientToScreen(&point);
  566. OnCaptionLButtonDown(point);
  567. }
  568. }
  569. void CXTPDockingPaneSidePanel::OnLButtonDblClk(UINT /*nFlags*/, CPoint point)
  570. {
  571. if (HitTestCaptionButton(point))
  572. return;
  573. CRect rcCaption = GetPaintManager()->GetPaneCaptionRect(this);
  574. if (rcCaption.PtInRect(point))
  575. {
  576. GetDockingPaneManager()->ToggleDocking(GetTopContainer());
  577. }
  578. }
  579. void CXTPDockingPaneSidePanel::OnMouseMove(UINT nFlags, CPoint point)
  580. {
  581. m_pCaptionButtons->CheckForMouseOver(point);
  582. if (m_bCollapsed && point != CPoint(-1, -1) && !m_bExpanded)
  583. {
  584. TRACKMOUSEEVENT tme =
  585. {
  586. sizeof(TRACKMOUSEEVENT), TME_HOVER, m_hWnd, CXTPDockingPaneAutoHideWnd::m_nMouseHoverDelay
  587. };
  588. _TrackMouseEvent(&tme);
  589. }
  590. CWnd::OnMouseMove(nFlags, point);
  591. }
  592. LRESULT CXTPDockingPaneSidePanel::OnMouseHover(WPARAM, LPARAM)
  593. {
  594. if (m_bCollapsed)
  595. {
  596. if (!CXTPDrawHelpers::IsTopParentActive(m_hWnd))
  597. return 1;
  598. Expand();
  599. }
  600. return 1;
  601. }
  602. void CXTPDockingPaneSidePanel::OnMouseLeave()
  603. {
  604. OnMouseMove(0, CPoint(-1, -1));
  605. }
  606. void CXTPDockingPaneSidePanel::OnPinButtonClick()
  607. {
  608. if (!m_hWnd)
  609. return;
  610. BOOL bPinning = m_bCollapsed;
  611. if (OnAction(bPinning ? xtpPaneActionPinning : xtpPaneActionUnpinning))
  612. return;
  613. if (!m_bCollapsed)
  614. {
  615. Collapse(TRUE);
  616. }
  617. else
  618. {
  619. if (m_nStepsCount != m_nSlideStep)
  620. {
  621. SetWindowPos(0, 0, 0, m_rcWindow.Width(), m_rcWindow.Height(), SWP_NOZORDER | SWP_NOMOVE);
  622. }
  623. m_bCollapsed = FALSE;
  624. m_bExpanded = FALSE;
  625. KillTimer(TID_CHECKACTIVE);
  626. KillTimer(TID_SLIDEOUT);
  627. }
  628. InvalidatePane(FALSE);
  629. OnAction(bPinning ? xtpPaneActionPinned : xtpPaneActionUnpinned);
  630. }
  631. int CXTPDockingPaneSidePanel::GetMinHeight()
  632. {
  633. CRect rc = GetPaintManager()->GetPaneCaptionRect(this);
  634. return 2 + (IsHorizontal() ? rc.Height() : rc.Width());
  635. }
  636. void CXTPDockingPaneSidePanel::DoSlideStep(BOOL bActivate)
  637. {
  638. m_bInRecalcLayout = TRUE;
  639. int nMinHeight = GetMinHeight();
  640. BOOL bHorizontal = IsHorizontal();
  641. CXTPWindowRect rc(this);
  642. int nSize = max(nMinHeight, m_nSlideStep * ( bHorizontal ? m_rcWindow.Height() : m_rcWindow.Width()) / m_nStepsCount);
  643. switch (m_direction)
  644. {
  645. case xtpPaneDockLeft: rc.right = rc.left + nSize; break;
  646. case xtpPaneDockTop: rc.bottom = rc.top + nSize; break;
  647. case xtpPaneDockRight: rc.left = rc.right - nSize; break;
  648. case xtpPaneDockBottom: rc.top = rc.bottom - nSize; break;
  649. }
  650. GetParent()->ScreenToClient(rc);
  651. SetWindowPos(&CWnd::wndTop, rc.left, rc.top, rc.Width(), rc.Height(), (!bActivate ? SWP_NOZORDER | SWP_NOACTIVATE : SWP_NOACTIVATE));
  652. Invalidate(FALSE);
  653. CRect rcClient;
  654. GetClientRect(rcClient);
  655. GetPaintManager()->AdjustClientRect(this, rcClient);
  656. CXTPDockingPaneTabbedContainer* pContainer = GetTopContainer();
  657. if (pContainer)
  658. {
  659. pContainer->OnSizeParent(this, rcClient, NULL);
  660. }
  661. m_bInRecalcLayout = FALSE;
  662. }
  663. void CXTPDockingPaneSidePanel::Expand()
  664. {
  665. if (m_bCollapsed)
  666. {
  667. if (m_bSlideOut)
  668. {
  669. m_bSlideOut = FALSE;
  670. m_bExpanded = FALSE;
  671. KillTimer(TID_SLIDEOUT);
  672. OnAction(xtpPaneActionCollapsed);
  673. }
  674. if (OnAction(xtpPaneActionExpanding))
  675. return;
  676. m_bExpanded = TRUE;
  677. m_nSlideStep = m_nStepsCount = ResetStepsCount();
  678. DoSlideStep(TRUE);
  679. m_nDeactivationCount = 8;
  680. SetTimer(TID_CHECKACTIVE, 100, NULL);
  681. OnAction(xtpPaneActionExpanded);
  682. }
  683. }
  684. void CXTPDockingPaneSidePanel::Collapse(BOOL bDelay)
  685. {
  686. m_nSlideStep = m_nStepsCount = ResetStepsCount();
  687. m_bCollapsed = TRUE;
  688. m_bExpanded = TRUE;
  689. if (!bDelay)
  690. {
  691. if (!OnAction(xtpPaneActionCollapsing))
  692. {
  693. m_bExpanded = FALSE;
  694. m_nSlideStep = 0;
  695. DoSlideStep(FALSE);
  696. KillTimer(TID_SLIDEOUT);
  697. KillTimer(TID_CHECKACTIVE);
  698. OnAction(xtpPaneActionCollapsed);
  699. return;
  700. }
  701. }
  702. if (m_bSlideOut)
  703. {
  704. m_bSlideOut = FALSE;
  705. KillTimer(TID_SLIDEOUT);
  706. OnAction(xtpPaneActionCollapsed);
  707. }
  708. m_nDeactivationCount = 6;
  709. SetTimer(TID_CHECKACTIVE, 100, NULL);
  710. }
  711. void CXTPDockingPaneSidePanel::OnTimer(UINT_PTR nIDEvent)
  712. {
  713. if (nIDEvent == TID_SLIDEOUT && m_bSlideOut)
  714. {
  715. m_nSlideStep--;
  716. if (m_nSlideStep > -1)
  717. DoSlideStep();
  718. else
  719. {
  720. m_bSlideOut = FALSE;
  721. m_bExpanded = FALSE;
  722. KillTimer(TID_SLIDEOUT);
  723. OnAction(xtpPaneActionCollapsed);
  724. }
  725. }
  726. if (nIDEvent == TID_CHECKACTIVE)
  727. {
  728. CPoint pt;
  729. GetCursorPos(&pt);
  730. CWnd* pFocus = GetFocus();
  731. BOOL bActive = (pFocus->GetSafeHwnd() && (pFocus == this || IsChild(pFocus)));
  732. if (!bActive && !m_bSlideOut && !CXTPWindowRect(this).PtInRect(pt) && ::GetCapture() == NULL)
  733. {
  734. if (--m_nDeactivationCount <= 0)
  735. {
  736. if (OnAction(xtpPaneActionCollapsing))
  737. {
  738. m_nDeactivationCount = 6;
  739. return;
  740. }
  741. m_bSlideOut = TRUE;
  742. SetTimer(TID_SLIDEOUT, CXTPDockingPaneAutoHideWnd::m_nAnimationInterval, NULL);
  743. KillTimer(TID_CHECKACTIVE);
  744. }
  745. }
  746. }
  747. CMiniFrameWnd::OnTimer(nIDEvent);
  748. }
  749. void CXTPDockingPaneSidePanel::GetMinMaxInfo(LPMINMAXINFO pMinMaxInfo) const
  750. {
  751. CXTPDockingPaneBase::GetMinMaxInfo(pMinMaxInfo);
  752. if (IsEmpty())
  753. return;
  754. GetTopContainer()->GetMinMaxInfo(pMinMaxInfo);
  755. CSize szBorder(6, 6);
  756. int nCaptionHeight = GetPaintManager()->GetCaptionHeight();
  757. if (IsHorizontal()) szBorder.cy += nCaptionHeight; else szBorder.cx += nCaptionHeight;
  758. pMinMaxInfo->ptMinTrackSize.x += szBorder.cx;
  759. pMinMaxInfo->ptMinTrackSize.y += szBorder.cy;
  760. pMinMaxInfo->ptMaxTrackSize.x += szBorder.cx;
  761. pMinMaxInfo->ptMaxTrackSize.y += szBorder.cy;
  762. pMinMaxInfo->ptMinTrackSize.x = max(pMinMaxInfo->ptMinTrackSize.x, nCaptionHeight * 2);
  763. pMinMaxInfo->ptMinTrackSize.y = max(pMinMaxInfo->ptMinTrackSize.y, nCaptionHeight * 2);
  764. }
  765. BOOL CXTPDockingPaneSidePanel::IsHorizontal() const
  766. {
  767. return m_direction == xtpPaneDockTop || m_direction == xtpPaneDockBottom;
  768. }
  769. BOOL CXTPDockingPaneSidePanel::IsResizable(int nHit)
  770. {
  771. if (IsHorizontal())
  772. {
  773. if (nHit == HTTOP) return m_direction == xtpPaneDockBottom;
  774. if (nHit == HTBOTTOM) return m_direction == xtpPaneDockTop;
  775. if (nHit == HTLEFT || nHit == HTRIGHT) return TRUE;
  776. }
  777. else
  778. {
  779. if (nHit == HTLEFT) return m_direction == xtpPaneDockRight;
  780. if (nHit == HTRIGHT) return m_direction == xtpPaneDockLeft;
  781. if (nHit == HTTOP || nHit == HTBOTTOM) return TRUE;
  782. }
  783. return FALSE;
  784. }
  785. void CXTPDockingPaneSidePanel::OnNcLButtonDown(UINT nHitTest, CPoint point)
  786. {
  787. if (nHitTest >= HTSIZEFIRST && nHitTest <= HTSIZELAST)
  788. {
  789. _RestoreFocus();
  790. Expand();
  791. SetCapture();
  792. m_pLayout->MoveToTail(this);
  793. CXTPWindowRect rcWindow(this);
  794. CRect rcClient(GetDockingPaneManager()->GetClientPane()->GetPaneWindowRect());
  795. rcClient.DeflateRect(GetDockingPaneManager()->GetSideDockingMargin());
  796. rcWindow.OffsetRect(-rcClient.TopLeft());
  797. MINMAXINFO mmi;
  798. GetMinMaxInfo(&mmi);
  799. BOOL bResizeTop = nHitTest == HTTOP || nHitTest == HTTOPLEFT || nHitTest == HTTOPRIGHT;
  800. BOOL bResizeBottom = nHitTest == HTBOTTOM || nHitTest == HTBOTTOMLEFT || nHitTest == HTBOTTOMRIGHT;
  801. BOOL bResizeRight = nHitTest == HTRIGHT || nHitTest == HTTOPRIGHT || nHitTest == HTBOTTOMRIGHT;
  802. BOOL bResizeLeft = nHitTest == HTLEFT || nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMLEFT;
  803. while (::GetCapture() == m_hWnd)
  804. {
  805. MSG msg;
  806. while (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_NOREMOVE))
  807. {
  808. if (!GetMessage(&msg, NULL, WM_PAINT, WM_PAINT))
  809. return;
  810. DispatchMessage(&msg);
  811. }
  812. if (!GetMessage(&msg, NULL, 0, 0))
  813. break;
  814. if (msg.message == WM_MOUSEMOVE)
  815. {
  816. CPoint pt = CPoint(msg.lParam);
  817. ClientToScreen(&pt);
  818. CPoint ptOffset = pt - point;
  819. point = pt;
  820. if (bResizeTop) rcWindow.top += ptOffset.y;
  821. if (bResizeBottom) rcWindow.bottom += ptOffset.y;
  822. if (bResizeRight) rcWindow.right += ptOffset.x;
  823. if (bResizeLeft) rcWindow.left += ptOffset.x;
  824. m_rcWindow = rcWindow;
  825. if (m_rcWindow.Height() > mmi.ptMaxTrackSize.y)
  826. {
  827. if (bResizeTop) m_rcWindow.top = m_rcWindow.bottom - mmi.ptMaxTrackSize.y; else m_rcWindow.bottom = m_rcWindow.top + mmi.ptMaxTrackSize.y;
  828. }
  829. if (m_rcWindow.Height() < mmi.ptMinTrackSize.y)
  830. {
  831. if (bResizeTop) m_rcWindow.top = m_rcWindow.bottom - mmi.ptMinTrackSize.y; else m_rcWindow.bottom = m_rcWindow.top + mmi.ptMinTrackSize.y;
  832. }
  833. if (m_rcWindow.Width() > mmi.ptMaxTrackSize.x)
  834. {
  835. if (bResizeLeft) m_rcWindow.left = m_rcWindow.right - mmi.ptMaxTrackSize.x; else m_rcWindow.right = m_rcWindow.left + mmi.ptMaxTrackSize.x;
  836. }
  837. if (m_rcWindow.Width() < mmi.ptMinTrackSize.x)
  838. {
  839. if (bResizeLeft) m_rcWindow.left = m_rcWindow.right - mmi.ptMinTrackSize.x; else m_rcWindow.right = m_rcWindow.left + mmi.ptMinTrackSize.x;
  840. }
  841. RecalcLayout(FALSE);
  842. }
  843. else if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE) break;
  844. else if (msg.message == WM_LBUTTONUP) break;
  845. else ::DispatchMessage(&msg);
  846. }
  847. if (CWnd::GetCapture() == this) ReleaseCapture();
  848. }
  849. }
  850. LRESULT CXTPDockingPaneSidePanel::OnNcHitTest(CPoint point)
  851. {
  852. if (m_bCollapsed && !m_bExpanded)
  853. return HTCLIENT;
  854. CXTPWindowRect rcWindow(this);
  855. CRect rcBorders = rcWindow;
  856. rcBorders.DeflateRect(3, 3);
  857. if (rcWindow.PtInRect(point) && !rcBorders.PtInRect(point))
  858. {
  859. rcBorders.DeflateRect(8, 8);
  860. int ht = 0;
  861. if (point.y < rcBorders.top && IsResizable(HTTOP))
  862. ht = (HTTOP - HTSIZEFIRST + 1);
  863. else if (point.y >= rcBorders.bottom  && IsResizable(HTBOTTOM))
  864. ht = (HTBOTTOM - HTSIZEFIRST + 1);
  865. if (point.x < rcBorders.left && IsResizable(HTLEFT))
  866. ht += (HTLEFT - HTSIZEFIRST + 1);
  867. else if (point.x >= rcBorders.right  && IsResizable(HTRIGHT))
  868. ht += (HTRIGHT - HTSIZEFIRST + 1);
  869. return (LRESULT)(ht + HTSIZEFIRST - 1);
  870. }
  871. return HTCLIENT;
  872. }
  873. INT_PTR CXTPDockingPaneSidePanel::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
  874. {
  875. ASSERT_VALID(this);
  876. ASSERT(::IsWindow(m_hWnd));
  877. // check child windows first by calling CControlBar
  878. INT_PTR nHit = CWnd::OnToolHitTest(point, pTI);
  879. if (nHit != -1)
  880. return nHit;
  881. CXTPDockingPaneCaptionButton* pButton = HitTestCaptionButton(point);
  882. if (pButton)
  883. {
  884. nHit = (INT_PTR)pButton->GetID();
  885. CString strTip;
  886. XTPResourceManager()->LoadString(&strTip, (UINT)nHit);
  887. if (strTip.GetLength() == 0)
  888. return -1;
  889. CXTPToolTipContext::FillInToolInfo(pTI, m_hWnd, pButton->GetRect(), nHit, strTip);
  890. return nHit;
  891. }
  892. return -1;
  893. }
  894. BOOL CXTPDockingPaneSidePanel::OnWndMsg(UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult)
  895. {
  896. CXTPDockingPaneManager* pManager = GetDockingPaneManager();
  897. if (pManager)
  898. {
  899. pManager->GetToolTipContext()->FilterToolTipMessage(this, message, wParam, lParam);
  900. }
  901. return CMiniFrameWnd::OnWndMsg(message, wParam, lParam, pResult);
  902. }
  903. void CXTPDockingPaneSidePanel::OnRButtonUp(UINT /*nFlags*/, CPoint point)
  904. {
  905. XTP_DOCKINGPANE_CLICK menu;
  906. menu.pPane = GetSelectedPane();
  907. menu.pContainer = this;
  908. ClientToScreen(&point);
  909. menu.pt = point;
  910. menu.rcExclude.SetRectEmpty();
  911. if (GetDockingPaneManager()->NotifyOwner(XTP_DPN_CONTEXTMENU, (LPARAM)&menu))
  912. return;
  913. }