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

对话框与窗口

开发平台:

Visual C++

  1. // XTPTaskPanelGroup.cpp : implementation of the CXTPTaskPanelGroup class.
  2. //
  3. // This file is a part of the XTREME TASKPANEL 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/XTPImageManager.h"
  22. #include "Common/XTPPropExchange.h"
  23. #include "XTPTaskPanelGroup.h"
  24. #include "XTPTaskPanelGroupItem.h"
  25. #include "XTPTaskPanelItems.h"
  26. #include "XTPTaskPanel.h"
  27. #include "XTPTaskPanelPaintManager.h"
  28. #ifdef _DEBUG
  29. #define new DEBUG_NEW
  30. #undef THIS_FILE
  31. static char THIS_FILE[] = __FILE__;
  32. #endif
  33. /////////////////////////////////////////////////////////////////////////////
  34. // CXTPTaskPanelGroup
  35. IMPLEMENT_SERIAL(CXTPTaskPanelGroup, CXTPTaskPanelItem, VERSIONABLE_SCHEMA | _XTP_SCHEMA_CURRENT)
  36. CXTPTaskPanelGroup::CXTPTaskPanelGroup(CXTPTaskPanel* pPanel)
  37. {
  38. m_typeItem = xtpTaskItemTypeGroup;
  39. m_bSpecial = FALSE;
  40. m_rcMarginsOuter = CXTPTaskPanelPaintManager::rectDefault;
  41. m_rcMarginsInner = CXTPTaskPanelPaintManager::rectDefault;
  42. m_rcGroupTarget.SetRectEmpty();
  43. m_rcGroupCurrent.SetRectEmpty();
  44. m_pItems = new CXTPTaskPanelGroupItems(pPanel);
  45. m_pItems->m_pOwner = this;
  46. m_nCaptionHeight = 0;
  47. m_nExpandedClientHeight = 0;
  48. m_bCaptionVisible = TRUE;
  49. m_bExpandable = TRUE;
  50. m_bExpanded = TRUE;
  51. m_bExpanding = FALSE;
  52. m_itemLayout = xtpTaskItemLayoutDefault;
  53. m_nScrollOffset = 0;
  54. m_nItemsInRow = 1;
  55. m_szItemIcon = CSize(0);
  56. m_szClientBitmap = CSize(0);
  57. m_nMinClientHeight = 0;
  58. EnableAutomation();
  59. }
  60. CXTPTaskPanelGroup::~CXTPTaskPanelGroup()
  61. {
  62. m_pItems->InternalRelease();
  63. }
  64. void CXTPTaskPanelGroup::OnRemoved()
  65. {
  66. m_pItems->Clear(FALSE);
  67. m_pItems->m_pPanel = NULL;
  68. }
  69. int CXTPTaskPanelGroup::GetMinimumClientHeight() const
  70. {
  71. return max(m_nMinClientHeight, GetTaskPanel()->GetMinimumGroupClientHeight());
  72. }
  73. void CXTPTaskPanelGroup::SetMinimumClientHeight(int nMinClientHeight)
  74. {
  75. m_nMinClientHeight = nMinClientHeight;
  76. }
  77. CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::AddLinkItem(UINT nID, int nImage)
  78. {
  79. CXTPTaskPanel::CRepositionContext context(m_pPanel);
  80. CXTPTaskPanelGroupItem* pItem = (CXTPTaskPanelGroupItem*)m_pItems->Add(new CXTPTaskPanelGroupItem(), nID);
  81. pItem->SetIconIndex(nImage);
  82. pItem->SetType(xtpTaskItemTypeLink);
  83. return pItem;
  84. }
  85. CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::AddTextItem(LPCTSTR strText)
  86. {
  87. CXTPTaskPanel::CRepositionContext context(m_pPanel);
  88. CXTPTaskPanelGroupItem* pItem = (CXTPTaskPanelGroupItem*)m_pItems->Add(new CXTPTaskPanelGroupItem(), 0);
  89. pItem->SetCaption(strText);
  90. return pItem;
  91. }
  92. CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::AddControlItem(HWND hWnd)
  93. {
  94. CXTPTaskPanel::CRepositionContext context(m_pPanel);
  95. CXTPTaskPanelGroupItem* pItem = (CXTPTaskPanelGroupItem*)m_pItems->Add(new CXTPTaskPanelGroupItem(), 0);
  96. pItem->SetControlHandle(hWnd);
  97. return pItem;
  98. }
  99. CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::GetAt(int nIndex) const
  100. {
  101. return (CXTPTaskPanelGroupItem*)m_pItems->GetAt(nIndex);
  102. }
  103. CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::FindItem(int nID) const
  104. {
  105. return (CXTPTaskPanelGroupItem*)m_pItems->Find(nID);
  106. }
  107. BOOL CXTPTaskPanelGroup::IsDirty() const
  108. {
  109. return (m_rcGroupCurrent != m_rcGroupTarget) && IsVisible();
  110. }
  111. int CXTPTaskPanelGroup::CalcInsideHeight()
  112. {
  113. CRect rc;
  114. m_pPanel->GetClientRect(&rc);
  115. int nInsideHeight = rc.Height();
  116. CXTPTaskPanelPaintManager* pPaintManager = GetPaintManager();
  117. int nGroupSpacing = pPaintManager->GetGroupSpacing(m_pPanel);
  118. CRect rcMargins = pPaintManager->GetControlMargins(m_pPanel);
  119. int nGroupCount = m_pPanel->GetGroupCount();
  120. int nVisibleCount = 0;
  121. for (int i = 0; i < nGroupCount; i++)
  122. {
  123. CXTPTaskPanelGroup* pGroup = m_pPanel->GetAt(i);
  124. if (!pGroup->IsVisible())
  125. continue;
  126. nVisibleCount++;
  127. CRect rcMarginsOuter = pPaintManager->GetGroupOuterMargins(pGroup);
  128. nInsideHeight -= pGroup->m_nCaptionHeight + rcMarginsOuter.top + rcMarginsOuter.bottom;
  129. if (pGroup->IsExpanded() && pGroup != m_pPanel->GetActiveGroup())
  130. nInsideHeight -= pGroup->m_nExpandedClientHeight;
  131. }
  132. nInsideHeight -= nVisibleCount > 0 ? nGroupSpacing * (nVisibleCount - 1) : 0;
  133. nInsideHeight -= rcMargins.top + rcMargins.bottom;
  134. return nInsideHeight;
  135. }
  136. CSize CXTPTaskPanelGroup::GetItemIconSize() const
  137. {
  138. return m_szItemIcon == CSize(0) ? GetTaskPanel()->GetItemIconSize() : m_szItemIcon;
  139. }
  140. void CXTPTaskPanelGroup::SetIconSize(CSize szItemIcon)
  141. {
  142. m_szItemIcon = szItemIcon;
  143. GetTaskPanel()->Reposition();
  144. }
  145. void CXTPTaskPanelGroup::OnCalcClientHeight(CDC* pDC, CRect rc)
  146. {
  147. CXTPTaskPanelPaintManager* pPaintManager = GetPaintManager();
  148. CRect rcMarginsOuter = pPaintManager->GetGroupOuterMargins(this);
  149. CRect rcMarginsInner = pPaintManager->GetGroupInnerMargins(this);
  150. rc.DeflateRect(rcMarginsOuter);
  151. CRect rcItems(rc);
  152. rcItems.DeflateRect(rcMarginsInner);
  153. m_nItemsInRow = 1;
  154. int nItemCount = GetItemCount();
  155. if (GetItemLayout() == xtpTaskItemLayoutImages)
  156. {
  157. CSize szIcon = GetItemIconSize();
  158. CRect rcInnerMargins(pPaintManager->m_rcImageLayoutIconPadding);
  159. CSize szButton(szIcon.cx + rcInnerMargins.right + rcInnerMargins.left,
  160. szIcon.cy + rcInnerMargins.top + rcInnerMargins.bottom);
  161. int nRowIcons = max(1, rcItems.Width() / szButton.cx), x = 0, y = 0;
  162. BOOL bWrap = FALSE;
  163. for (int i = 0; i < nItemCount; i++)
  164. {
  165. CXTPTaskPanelGroupItem* pItem = GetAt(i);
  166. if (!pItem->IsVisible())
  167. continue;
  168. if (bWrap)
  169. {
  170. x = 0;
  171. y++;
  172. bWrap = FALSE;
  173. }
  174. CRect rcItem(CPoint(rcItems.left + x * szButton.cx, rcItems.top + y * szButton.cy), szButton);
  175. pItem->OnReposition(rcItem);
  176. if (++x == nRowIcons)
  177. bWrap = TRUE;
  178. }
  179. rcItems.bottom = rcItems.top + rcMarginsInner.bottom + szButton.cy * (y + 1);
  180. m_nItemsInRow = nRowIcons;
  181. SetOffsetItem(m_nScrollOffset);
  182. }
  183. else
  184. {
  185. BOOL bMultiColumn = m_pPanel->IsMultiColumn();
  186. int nRowHeight = 0;
  187. CRect rcItemOuterMargins(0, 0, 0, 0);
  188. int nColumnWidth = m_pPanel->GetColumnWidth();
  189. ASSERT(nColumnWidth > 0);
  190. int x = 0;
  191. BOOL bWrap = FALSE;
  192. int nRowIcons = max(1, rcItems.Width() / nColumnWidth);
  193. for (int i = 0; i < nItemCount; i++)
  194. {
  195. CXTPTaskPanelGroupItem* pItem = GetAt(i);
  196. if (!pItem->IsVisible())
  197. continue;
  198. if (bMultiColumn)
  199. {
  200. if (bWrap)
  201. {
  202. rcItems.top += nRowHeight;
  203. nRowHeight = 0;
  204. x = 0;
  205. bWrap = FALSE;
  206. }
  207. CRect rcItem = pItem->OnReposition(CRect(rcItems.left + x * nColumnWidth, rcItems.top, rcItems.left + (x + 1) * nColumnWidth, rcItems.bottom));
  208. rcItemOuterMargins = pPaintManager->GetItemOuterMargins(pItem);
  209. nRowHeight = max(nRowHeight, rcItem.Height() + rcItemOuterMargins.bottom);
  210. if (++x == nRowIcons)
  211. bWrap = TRUE;
  212. }
  213. else
  214. {
  215. CRect rcItem = pItem->OnReposition(rcItems);
  216. rcItems.top = rcItem.bottom + pPaintManager->GetItemOuterMargins(pItem).bottom;
  217. }
  218. }
  219. if (bMultiColumn)
  220. {
  221. rcItems.top += nRowHeight;
  222. m_nItemsInRow = nRowIcons;
  223. }
  224. rcItems.bottom = rcItems.top + rcMarginsInner.bottom;
  225. }
  226. int nMinClientHeight = GetMinimumClientHeight();
  227. if (rcItems.bottom - rc.top < nMinClientHeight)
  228. rcItems.bottom = rc.top + nMinClientHeight;
  229. m_nExpandedClientHeight = rcItems.bottom - rc.top;
  230. m_nCaptionHeight = pPaintManager->DrawGroupCaption(pDC, this, FALSE);
  231. }
  232. CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::GetNextVisibleItem(int nIndex, int nDirection) const
  233. {
  234. return GetAt(m_pItems->GetNextVisibleIndex(nIndex, nDirection));
  235. }
  236. void CXTPTaskPanelGroup::RepositionScrollOffset()
  237. {
  238. int nItemCount = GetItemCount();
  239. int nLastVisibleItem = m_pItems->GetNextVisibleIndex(nItemCount, -1);
  240. int nScrollOffset = min(GetOffsetItem(), nLastVisibleItem);
  241. if (nScrollOffset > 0)
  242. {
  243. CRect rcItem(GetAt(nLastVisibleItem)->GetItemRect());
  244. int nTopMargin = GetPaintManager()->GetGroupInnerMargins(this).top;
  245. while ((nScrollOffset > 0) && ((rcItem.bottom - GetAt(nScrollOffset - 1)->GetItemRect().top + nTopMargin
  246. < m_nExpandedClientHeight) || !GetAt(nScrollOffset - 1)->IsVisible()))
  247. {
  248. nScrollOffset--;
  249. }
  250. }
  251. SetOffsetItem(nScrollOffset, FALSE);
  252. for (int i = 0; i < nItemCount; i++)
  253. {
  254. CXTPTaskPanelGroupItem* pItem = GetAt(i);
  255. if (pItem->IsItemFocused() || (pItem->IsItemSelected() && GetTaskPanel()->m_bSelectItemOnFocus))
  256. {
  257. EnsureVisible(pItem, FALSE);
  258. break;
  259. }
  260. }
  261. }
  262. void CXTPTaskPanelGroup::RepositionAutoHeightControls(int nHeightOffset)
  263. {
  264. if (GetItemLayout() == xtpTaskItemLayoutImages)
  265. return;
  266. int nCount = 0, i, nTotalHeight = 0, nItemCount = GetItemCount(), nOffset = 0;
  267. for (i = 0; i < nItemCount; i++)
  268. {
  269. CXTPTaskPanelGroupItem* pItem = GetAt(i);
  270. if (pItem->IsAutoHeight() && pItem->IsVisible())
  271. {
  272. nCount++;
  273. nTotalHeight += max(1, pItem->GetSize().cy);
  274. }
  275. }
  276. if (nCount == 0)
  277. return;
  278. for (i = 0; i < nItemCount; i++)
  279. {
  280. CXTPTaskPanelGroupItem* pItem = GetAt(i);
  281. pItem->m_rcItem.OffsetRect(0, nOffset);
  282. if (pItem->IsAutoHeight() && pItem->IsVisible())
  283. {
  284. int nItemHeight = max(1, pItem->GetSize().cy);
  285. int nItemHeightOffset = nCount > 1 ? (int)(nItemHeight* nHeightOffset / nTotalHeight) : nHeightOffset;
  286. nCount--;
  287. nTotalHeight -= nItemHeight;
  288. nHeightOffset -= nItemHeightOffset;
  289. pItem->m_rcItem.bottom += nItemHeightOffset;
  290. nOffset += nItemHeightOffset;
  291. }
  292. }
  293. }
  294. CRect CXTPTaskPanelGroup::OnReposition(CRect rc, BOOL bRecalcOnly)
  295. {
  296. if (m_pPanel->IsExplorerBehaviour())
  297. SetOffsetItem(0, FALSE);
  298. CXTPTaskPanelPaintManager* pPaintManager = GetPaintManager();
  299. CRect rcMarginsOuter = pPaintManager->GetGroupOuterMargins(this);
  300. rc.DeflateRect(rcMarginsOuter);
  301. m_rcGroupTarget = rc;
  302. if (!m_pPanel->IsExplorerBehaviour() && (m_pPanel->GetActiveGroup() == this || IsExpanding()))
  303. {
  304. CRect rcMarginsInner = pPaintManager->GetGroupInnerMargins(this);
  305. int nInsideHeight = CalcInsideHeight();
  306. int nButtonHeight = max(32, GetItemIconSize().cy + rcMarginsInner.bottom);
  307. int nExpandedClientHeight = max(nButtonHeight + rcMarginsInner.top + 2, nInsideHeight);
  308. int nMinClientHeight = GetMinimumClientHeight();
  309. nExpandedClientHeight = max(nMinClientHeight, nExpandedClientHeight);
  310. if (nExpandedClientHeight > m_nExpandedClientHeight)
  311. {
  312. RepositionAutoHeightControls(nExpandedClientHeight - m_nExpandedClientHeight);
  313. }
  314. m_nExpandedClientHeight = nExpandedClientHeight;
  315. RepositionScrollOffset();
  316. }
  317. int nClientHeight = IsExpanded() ? m_nExpandedClientHeight : 0;
  318. m_rcGroupTarget.bottom = m_rcGroupTarget.top + m_nCaptionHeight + nClientHeight;
  319. m_rcGroupCurrent.left = m_rcGroupTarget.left;
  320. m_rcGroupCurrent.right = m_rcGroupTarget.right;
  321. if (!bRecalcOnly || !m_pPanel->m_bAnimation) OnAnimate(0);
  322. else if (!IsDirty()) OnAnimate(0);
  323. return m_rcGroupTarget;
  324. }
  325. #define MOVETO(A, B, Step) if (A != B) A += max(1, abs(A - B)/Step) * (A > B ? -1 : 1);
  326. void CXTPTaskPanelGroup::OnAnimate(int nStep)
  327. {
  328. if (nStep < 1)
  329. {
  330. m_rcGroupCurrent = m_rcGroupTarget;
  331. }
  332. else
  333. {
  334. MOVETO(m_rcGroupCurrent.top, m_rcGroupTarget.top, nStep);
  335. MOVETO(m_rcGroupCurrent.bottom, m_rcGroupTarget.bottom, nStep);
  336. }
  337. if (!IsDirty() && m_bExpanding)
  338. {
  339. m_bExpanding = FALSE;
  340. m_pPanel->NotifyOwner(XTP_TPN_GROUPEXPANDED, (LPARAM)this);
  341. }
  342. for (int i = 0; i < GetItemCount(); i++)
  343. {
  344. CXTPTaskPanelGroupItem* pItem = GetAt(i);
  345. pItem->OnAnimate(nStep);
  346. }
  347. }
  348. void CXTPTaskPanelGroup::OnPaint(CDC* pDC)
  349. {
  350. GetPaintManager()->DrawGroupCaption(pDC, this, TRUE);
  351. GetPaintManager()->DrawGroupClient(pDC, this);
  352. }
  353. CRect CXTPTaskPanelGroup::GetCaptionRect() const
  354. {
  355. int nCaptionRight = m_rcGroupCurrent.right;
  356. if (m_pPanel->GetScrollButton(TRUE)->pGroupCaption == this)
  357. nCaptionRight = m_pPanel->GetScrollButton(TRUE)->rcButton.left - GetPaintManager()->GetGroupSpacing(m_pPanel) - 1;
  358. if (m_pPanel->GetScrollButton(FALSE)->pGroupCaption == this)
  359. nCaptionRight = m_pPanel->GetScrollButton(FALSE)->rcButton.left - GetPaintManager()->GetGroupSpacing(m_pPanel) - 1;
  360. return CRect(m_rcGroupCurrent.left, m_rcGroupCurrent.top, nCaptionRight, m_rcGroupCurrent.top + m_nCaptionHeight);
  361. }
  362. CRect CXTPTaskPanelGroup::GetTargetCaptionRect() const
  363. {
  364. int nCaptionRight = m_rcGroupTarget.right;
  365. if (m_pPanel->GetScrollButton(TRUE)->pGroupCaption == this)
  366. nCaptionRight = m_pPanel->GetScrollButton(TRUE)->rcButton.left - GetPaintManager()->GetGroupSpacing(m_pPanel) - 1;
  367. if (m_pPanel->GetScrollButton(FALSE)->pGroupCaption == this)
  368. nCaptionRight = m_pPanel->GetScrollButton(FALSE)->rcButton.left - GetPaintManager()->GetGroupSpacing(m_pPanel) - 1;
  369. return CRect(m_rcGroupTarget.left, m_rcGroupTarget.top, nCaptionRight, m_rcGroupTarget.top + m_nCaptionHeight);
  370. }
  371. CRect CXTPTaskPanelGroup::GetClientRect() const
  372. {
  373. return CRect(m_rcGroupCurrent.left, m_rcGroupCurrent.top + m_nCaptionHeight, m_rcGroupCurrent.right, m_rcGroupCurrent.bottom);
  374. }
  375. CRect CXTPTaskPanelGroup::GetTargetClientRect() const
  376. {
  377. return CRect(m_rcGroupTarget.left, m_rcGroupTarget.top + m_nCaptionHeight, m_rcGroupTarget.right, m_rcGroupTarget.bottom);
  378. }
  379. BOOL CXTPTaskPanelGroup::IsAcceptFocus() const
  380. {
  381. return CXTPTaskPanelItem::IsAcceptFocus() && IsExpandable();
  382. }
  383. void CXTPTaskPanelGroup::SetSpecialGroup(BOOL bSpecial)
  384. {
  385. m_bSpecial = bSpecial;
  386. RedrawPanel();
  387. }
  388. BOOL CXTPTaskPanelGroup::IsSpecialGroup() const
  389. {
  390. return m_bSpecial;
  391. }
  392. void CXTPTaskPanelGroup::SetExpandable(BOOL bExpandable)
  393. {
  394. m_bExpandable = bExpandable;
  395. RedrawPanel();
  396. }
  397. BOOL CXTPTaskPanelGroup::IsExpandable() const
  398. {
  399. return m_bExpandable && m_pPanel->m_bExpandable && m_bEnabled;
  400. }
  401. void CXTPTaskPanelGroup::SetExpanded(BOOL bExpanded)
  402. {
  403. if (m_pPanel)
  404. m_pPanel->ExpandGroup(this, bExpanded);
  405. }
  406. BOOL CXTPTaskPanelGroup::IsExpanded() const
  407. {
  408. return m_pPanel ? m_pPanel->IsGroupExpanded(this) : FALSE;
  409. }
  410. BOOL CXTPTaskPanelGroup::IsExpanding() const
  411. {
  412. return m_bExpanding;
  413. }
  414. void CXTPTaskPanelGroup::ShowCaption(BOOL bShow)
  415. {
  416. if (m_bCaptionVisible != bShow)
  417. {
  418. m_bCaptionVisible = bShow;
  419. RepositionPanel();
  420. }
  421. }
  422. BOOL CXTPTaskPanelGroup::IsCaptionVisible() const
  423. {
  424. return m_bCaptionVisible;
  425. }
  426. void CXTPTaskPanelGroup::SetClientBitmap(UINT nID, COLORREF clrTransparent, BOOL bAlpha /*= FALSE*/)
  427. {
  428. m_ilClient.DeleteImageList();
  429. CBitmap bmp;
  430. bmp.LoadBitmap(nID);
  431. BITMAP bmpInfo;
  432. bmp.GetBitmap(&bmpInfo);
  433. CSize szBitmap(bmpInfo.bmWidth, bmpInfo.bmHeight);
  434. if (bAlpha)
  435. {
  436. m_ilClient.Create(szBitmap.cx, szBitmap.cy, ILC_COLOR32 | ILC_MASK, 0, 1);
  437. m_ilClient.Add(&bmp, (CBitmap*)NULL);
  438. }
  439. else
  440. {
  441. m_ilClient.Create(szBitmap.cx, szBitmap.cy, ILC_COLOR24 | ILC_MASK, 0, 1);
  442. m_ilClient.Add(&bmp, clrTransparent);
  443. }
  444. m_szClientBitmap = szBitmap;
  445. }
  446. void CXTPTaskPanelGroup::OnFillClient(CDC* pDC, CRect rc)
  447. {
  448. if (m_ilClient.GetSafeHandle() && m_ilClient.GetImageCount() == 1)
  449. {
  450. CPoint pt(rc.right - m_szClientBitmap.cx, rc.bottom - m_szClientBitmap.cy);
  451. m_ilClient.Draw(pDC, 0, pt, ILD_NORMAL);
  452. }
  453. }
  454. CRect CXTPTaskPanelGroup::GetHitTestRect() const
  455. {
  456. if (!m_pPanel)
  457. return CRect(0, 0, 0, 0);
  458. CRect rc = GetCaptionRect();
  459. rc.OffsetRect(0, -m_pPanel->GetScrollOffset());
  460. return rc;
  461. }
  462. CRect CXTPTaskPanelGroup::GetInvalidateRect() const
  463. {
  464. if (!m_pPanel)
  465. return CRect(0, 0, 0, 0);
  466. CRect rc = m_rcGroupCurrent;
  467. rc.OffsetRect(0, -m_pPanel->GetScrollOffset());
  468. return rc;
  469. }
  470. CXTPTaskPanelGroupItem* CXTPTaskPanelGroup::HitTest(CPoint pt, CRect* lpRect) const
  471. {
  472. if (!IsExpanded())
  473. return NULL;
  474. int nOffset = m_pPanel->GetScrollOffset() - m_nCaptionHeight - m_rcGroupCurrent.top + GetScrollOffsetPos();
  475. pt.y += nOffset;
  476. for (int i = 0; i < GetItemCount(); i++)
  477. {
  478. CXTPTaskPanelGroupItem* pItem = GetAt(i);
  479. CRect rcItem = pItem->GetItemRect();
  480. if (rcItem.PtInRect(pt) && pItem->IsVisible())
  481. {
  482. if (lpRect)
  483. {
  484. rcItem.OffsetRect(0, -nOffset);
  485. *lpRect = rcItem;
  486. }
  487. return pItem;
  488. }
  489. }
  490. return NULL;
  491. }
  492. XTPTaskPanelItemLayout CXTPTaskPanelGroup::GetItemLayout() const
  493. {
  494. if (m_itemLayout != xtpTaskItemLayoutDefault)
  495. return m_itemLayout;
  496. return m_pPanel->GetItemLayout();
  497. }
  498. void CXTPTaskPanelGroup::SetItemLayout(XTPTaskPanelItemLayout itemLayout)
  499. {
  500. if (itemLayout != m_itemLayout)
  501. {
  502. m_itemLayout = itemLayout;
  503. RepositionPanel();
  504. }
  505. }
  506. void CXTPTaskPanelGroup::SetSelectedItem(CXTPTaskPanelGroupItem* pSelectedItem)
  507. {
  508. int nCount = GetItemCount();
  509. for (int i = 0; i < nCount; i++)
  510. {
  511. CXTPTaskPanelGroupItem* pItem = GetAt(i);
  512. pItem->SetItemSelected(pSelectedItem == pItem);
  513. }
  514. }
  515. BOOL CXTPTaskPanelGroup::IsChildItemDragOver() const
  516. {
  517. return m_pPanel && m_pPanel->m_pItemDragOver &&
  518. m_pPanel->m_pItemDragOver->GetParentItems() == m_pItems;
  519. }
  520. int CXTPTaskPanelGroup::GetItemCount() const
  521. {
  522. return m_pItems->GetCount();
  523. }
  524. BOOL CXTPTaskPanelGroup::IsScrollButtonEnabled(BOOL bScrollButtonUp) const
  525. {
  526. CXTPTaskPanelGroupItem* pLastVisibleItem = (CXTPTaskPanelGroupItem*)m_pItems->GetLastVisibleItem();
  527. if (pLastVisibleItem == NULL)
  528. return FALSE;
  529. if (bScrollButtonUp)
  530. return m_nScrollOffset != 0;
  531. CRect rcItem(pLastVisibleItem->GetItemRect());
  532. return rcItem.bottom - GetScrollOffsetPos() > m_rcGroupTarget.Height() - m_nCaptionHeight;
  533. }
  534. int CXTPTaskPanelGroup::GetOffsetItem() const
  535. {
  536. if (m_nScrollOffset == 0)
  537. return 0;
  538. if (m_nScrollOffset < GetItemCount())
  539. {
  540. CXTPTaskPanelGroupItem* pItem = GetAt(m_nScrollOffset);
  541. if (pItem->IsVisible())
  542. return m_nScrollOffset;
  543. int nScrollOffset = m_pItems->GetNextVisibleIndex(m_nScrollOffset, +1);
  544. if (nScrollOffset != -1)
  545. return nScrollOffset;
  546. nScrollOffset = m_pItems->GetNextVisibleIndex(m_nScrollOffset, -1);
  547. if (nScrollOffset != -1)
  548. return nScrollOffset;
  549. }
  550. return 0;
  551. }
  552. int CXTPTaskPanelGroup::GetScrollOffsetPos() const
  553. {
  554. int nScrollOffset = GetOffsetItem();
  555. if (nScrollOffset > 0 && nScrollOffset < GetItemCount())
  556. {
  557. return GetAt(nScrollOffset)->GetItemRect().top - GetPaintManager()->GetGroupInnerMargins(this).top;
  558. }
  559. return 0;
  560. }
  561. void CXTPTaskPanelGroup::SetOffsetItem(int nScrollOffset, BOOL bUpdateScrollButtons /*= TRUE*/)
  562. {
  563. nScrollOffset = nScrollOffset - (nScrollOffset % m_nItemsInRow);
  564. if (nScrollOffset > GetItemCount() - 1)
  565. nScrollOffset = GetItemCount() - 1;
  566. if (nScrollOffset < 0)
  567. nScrollOffset = 0;
  568. if (m_nScrollOffset != nScrollOffset)
  569. {
  570. m_nScrollOffset = nScrollOffset;
  571. if (bUpdateScrollButtons)
  572. {
  573. OnAnimate(0);
  574. m_pPanel->UpdateScrollButtons();
  575. }
  576. RedrawPanel(FALSE);
  577. }
  578. }
  579. void CXTPTaskPanelGroup::Scroll(int nDelta)
  580. {
  581. SetOffsetItem(m_pItems->GetNextVisibleIndex(GetOffsetItem(), nDelta));
  582. }
  583. BOOL CXTPTaskPanelGroup::IsItemVisible(CXTPTaskPanelGroupItem* pItem, BOOL bAllowPart) const
  584. {
  585. if (!IsExpanded())
  586. return FALSE;
  587. if (!pItem || pItem->GetItemGroup() != this || !pItem->IsVisible())
  588. return FALSE;
  589. if (m_pPanel->IsExplorerBehaviour())
  590. return TRUE;
  591. int nIndex = pItem->GetIndex();
  592. if (m_nScrollOffset > nIndex)
  593. return FALSE;
  594. CRect rcItem(pItem->GetItemRect());
  595. if ((bAllowPart ? rcItem.top : rcItem.bottom) - GetScrollOffsetPos() > m_rcGroupTarget.Height() - m_nCaptionHeight)
  596. return FALSE;
  597. return TRUE;
  598. }
  599. void CXTPTaskPanelGroup::EnsureVisible(CXTPTaskPanelGroupItem* pItem, BOOL bUpdateScrollButtons /*= TRUE*/)
  600. {
  601. if (m_pPanel->IsExplorerBehaviour() || GetItemCount() == 0 || !IsExpanded())
  602. return;
  603. if (!pItem || pItem->GetItemGroup() != this || !pItem->IsVisible())
  604. return;
  605. int nIndex = pItem->GetIndex();
  606. if (m_nScrollOffset > nIndex)
  607. {
  608. SetOffsetItem(nIndex, bUpdateScrollButtons);
  609. return;
  610. }
  611. CRect rcItem(pItem->GetItemRect());
  612. if (rcItem.bottom - GetScrollOffsetPos() > m_nExpandedClientHeight)
  613. {
  614. int nTopMargin = GetPaintManager()->GetGroupInnerMargins(this).top;
  615. if (rcItem.top - GetScrollOffsetPos() <= nTopMargin)
  616. return;
  617. int nScrollOffset = m_nScrollOffset + 1;
  618. for (; nScrollOffset <= nIndex; nScrollOffset++)
  619. {
  620. CXTPTaskPanelGroupItem* pItemScroll = GetAt(nScrollOffset);
  621. if (!pItemScroll || !pItemScroll->IsVisible())
  622. continue;
  623. int nScrollOffsetPos = pItemScroll->GetItemRect().top - nTopMargin;
  624. if (rcItem.bottom - nScrollOffsetPos <= m_nExpandedClientHeight)
  625. break;
  626. if (rcItem.top - nScrollOffsetPos <= nTopMargin)
  627. break;
  628. }
  629. SetOffsetItem(nScrollOffset, bUpdateScrollButtons);
  630. }
  631. }
  632. void CXTPTaskPanelGroup::DoPropExchange(CXTPPropExchange* pPX)
  633. {
  634. CXTPTaskPanelItem::DoPropExchange(pPX);
  635. BOOL bExpanded = IsExpanded();
  636. PX_Bool(pPX, _T("CaptionVisible"), m_bCaptionVisible, TRUE);
  637. PX_Bool(pPX, _T("Expandable"), m_bExpandable, TRUE);
  638. PX_Bool(pPX, _T("Expanded"), bExpanded, FALSE);
  639. PX_Bool(pPX, _T("Special"), m_bSpecial, FALSE);
  640. PX_Enum(pPX, _T("Layout"), m_itemLayout, xtpTaskItemLayoutDefault);
  641. PX_Rect(pPX, _T("MarginsInner"), m_rcMarginsInner, CXTPTaskPanelPaintManager::rectDefault);
  642. PX_Rect(pPX, _T("MarginsOuter"), m_rcMarginsOuter, CXTPTaskPanelPaintManager::rectDefault);
  643. PX_Size(pPX, _T("IconSize"), m_szItemIcon, CSize(0));
  644. if (pPX->IsLoading())
  645. {
  646. m_pItems->m_pPanel = m_pPanel;
  647. SetExpanded(bExpanded);
  648. }
  649. CXTPPropExchangeSection secItems(pPX->GetSection(_T("Items")));
  650. m_pItems->DoPropExchange(&secItems);
  651. }
  652. HRESULT CXTPTaskPanelGroup::GetAccessibleState(VARIANT varChild, VARIANT* pvarState)
  653. {
  654. if (GetChildIndex(&varChild) != CHILDID_SELF)
  655. return E_INVALIDARG;
  656. CXTPTaskPanelItem::GetAccessibleState(varChild, pvarState);
  657. if (IsExpanded())
  658. pvarState->lVal |= STATE_SYSTEM_EXPANDED;
  659. else
  660. pvarState->lVal |= STATE_SYSTEM_COLLAPSED;
  661. return S_OK;
  662. }
  663. HRESULT CXTPTaskPanelGroup::GetAccessibleDefaultAction(VARIANT varChild, BSTR* pszDefaultAction)
  664. {
  665. if (GetChildIndex(&varChild) != CHILDID_SELF)
  666. return E_INVALIDARG;
  667. *pszDefaultAction = SysAllocString(L"Expand");
  668. return S_OK;
  669. }
  670. HRESULT CXTPTaskPanelGroup::AccessibleDoDefaultAction(VARIANT varChild)
  671. {
  672. SAFE_MANAGE_STATE(m_pModuleState);
  673. if (GetChildIndex(&varChild) != CHILDID_SELF)
  674. return E_INVALIDARG;
  675. SetExpanded(!IsExpanded());
  676. return S_OK;
  677. }
  678. /////////////////////////////////////////////////////////////////////////////
  679. // CXTPTaskPanelGroup message handlers