Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

845 lines
20 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Implements a list view for visgroups. Supports drag and drop, and
  4. // posts a registered windows message to the list view's parent window
  5. // when visgroups are hidden or shown.
  6. //
  7. //=============================================================================//
  8. #include "stdafx.h"
  9. #include "hammer.h"
  10. #include "GroupList.h"
  11. #include "MapDoc.h"
  12. #include "MapSolid.h"
  13. #include "MapWorld.h"
  14. #include "GlobalFunctions.h"
  15. #include "VisGroup.h"
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include <tier0/memdbgon.h>
  18. //
  19. // Timer IDs.
  20. //
  21. enum
  22. {
  23. TIMER_GROUP_DRAG_SCROLL = 1,
  24. };
  25. static const unsigned int g_uToggleStateMsg = ::RegisterWindowMessage(GROUPLIST_MSG_TOGGLE_STATE);
  26. static const unsigned int g_uLeftDragDropMsg = ::RegisterWindowMessage(GROUPLIST_MSG_LEFT_DRAG_DROP);
  27. static const unsigned int g_uRightDragDropMsg = ::RegisterWindowMessage(GROUPLIST_MSG_RIGHT_DRAG_DROP);
  28. static const unsigned int g_uSelChangeMsg = ::RegisterWindowMessage(GROUPLIST_MSG_SEL_CHANGE);
  29. BEGIN_MESSAGE_MAP(CGroupList, CTreeCtrl)
  30. //{{AFX_MSG_MAP(CGroupList)
  31. ON_NOTIFY_REFLECT(TVN_BEGINDRAG, OnBegindrag)
  32. ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndlabeledit)
  33. ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelChange)
  34. ON_WM_LBUTTONDOWN()
  35. ON_WM_LBUTTONUP()
  36. ON_WM_LBUTTONDBLCLK()
  37. ON_WM_RBUTTONDOWN()
  38. ON_WM_RBUTTONUP()
  39. ON_WM_MOUSEMOVE()
  40. ON_WM_TIMER()
  41. ON_WM_CONTEXTMENU()
  42. //}}AFX_MSG_MAP
  43. END_MESSAGE_MAP()
  44. //-----------------------------------------------------------------------------
  45. // Purpose:
  46. //-----------------------------------------------------------------------------
  47. CGroupList::CGroupList(void)
  48. {
  49. m_pDragImageList = NULL;
  50. m_hDragItem = NULL;
  51. m_bRButtonDown = false;
  52. }
  53. //-----------------------------------------------------------------------------
  54. // Purpose:
  55. //-----------------------------------------------------------------------------
  56. CGroupList::~CGroupList(void)
  57. {
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Purpose:
  61. //-----------------------------------------------------------------------------
  62. void CGroupList::EnableChecks(void)
  63. {
  64. if (!m_cNormalImageList.GetSafeHandle())
  65. {
  66. m_cNormalImageList.Create(IDB_VISGROUPSTATUS, 16, 1, RGB(255, 255, 255));
  67. m_cNormalImageList.SetOverlayImage(1, 1);
  68. m_cNormalImageList.SetOverlayImage(2, 2);
  69. }
  70. CTreeCtrl::SetImageList(&m_cNormalImageList, TVSIL_NORMAL);
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Purpose:
  74. // Input : pVisGroup -
  75. // hItemParent -
  76. //-----------------------------------------------------------------------------
  77. void CGroupList::AddVisGroupRecursive(CVisGroup *pVisGroup, HTREEITEM hItemParent)
  78. {
  79. HTREEITEM hItem = InsertItem(pVisGroup->GetName(), hItemParent, TVI_LAST);
  80. if (hItem != NULL)
  81. {
  82. SetItemData(hItem, (DWORD)pVisGroup);
  83. // Add the item to our flattened list.
  84. // VisGroupTreeItem_t item;
  85. // item.pVisGroup = pVisGroup;
  86. // item.hItem = hItem;
  87. // m_TreeItems.AddToTail(item);
  88. m_VisGroups.AddToTail(pVisGroup);
  89. int nCount = pVisGroup->GetChildCount();
  90. for (int i = 0; i < nCount; i++)
  91. {
  92. CVisGroup *pChild = pVisGroup->GetChild(i);
  93. AddVisGroupRecursive(pChild, hItem);
  94. }
  95. }
  96. }
  97. //-----------------------------------------------------------------------------
  98. // Purpose:
  99. // Input : pGroup -
  100. //-----------------------------------------------------------------------------
  101. void CGroupList::AddVisGroup(CVisGroup *pGroup)
  102. {
  103. AddVisGroupRecursive(pGroup, TVI_ROOT);
  104. }
  105. static void UnsetItemData_R( CTreeCtrl *pCtrl, HTREEITEM hItem )
  106. {
  107. pCtrl->SetItemData( hItem, 0 );
  108. HTREEITEM hChildItem = pCtrl->GetChildItem( hItem );
  109. while( hChildItem != NULL )
  110. {
  111. UnsetItemData_R( pCtrl, hChildItem );
  112. hChildItem = pCtrl->GetNextItem(hChildItem, TVGN_NEXT);
  113. }
  114. }
  115. //-----------------------------------------------------------------------------
  116. // Purpose:
  117. //-----------------------------------------------------------------------------
  118. void CGroupList::DeleteAllItems(void)
  119. {
  120. // Un-set all item data because sometimes during a delete it'll trigger selection change notifications
  121. // which might crash things later.
  122. if ( GetSafeHwnd() && m_VisGroups.Count() > 0 )
  123. {
  124. UnsetItemData_R( this, TVI_ROOT );
  125. }
  126. DeleteItem(TVI_ROOT);
  127. m_VisGroups.RemoveAll();
  128. }
  129. //-----------------------------------------------------------------------------
  130. // Purpose:
  131. //-----------------------------------------------------------------------------
  132. void CGroupList::EnsureVisible(CVisGroup *pVisGroup)
  133. {
  134. //DBG("EnsureVisible: %s\n", pVisGroup->GetName());
  135. HTREEITEM hItem = FindVisGroupItem(pVisGroup);
  136. if (hItem)
  137. {
  138. CTreeCtrl::EnsureVisible(hItem);
  139. }
  140. }
  141. //-----------------------------------------------------------------------------
  142. // Purpose:
  143. //-----------------------------------------------------------------------------
  144. void CGroupList::ExpandRecursive(HTREEITEM hItem)
  145. {
  146. if (hItem)
  147. {
  148. Expand(hItem, TVE_EXPAND);
  149. if (ItemHasChildren(hItem))
  150. {
  151. HTREEITEM hChildItem = GetChildItem(hItem);
  152. while (hChildItem != NULL)
  153. {
  154. ExpandRecursive(hChildItem);
  155. hChildItem = GetNextItem(hChildItem, TVGN_NEXT);
  156. }
  157. }
  158. }
  159. }
  160. //-----------------------------------------------------------------------------
  161. // Purpose:
  162. //-----------------------------------------------------------------------------
  163. void CGroupList::ExpandAll(void)
  164. {
  165. HTREEITEM hItem = GetRootItem();
  166. while (hItem)
  167. {
  168. ExpandRecursive(hItem);
  169. hItem = GetNextItem(hItem, TVGN_NEXT);
  170. }
  171. }
  172. //-----------------------------------------------------------------------------
  173. // Purpose: Returns the tree item in the given subtree associated with the given
  174. // visgroup, NULL if none.
  175. //-----------------------------------------------------------------------------
  176. HTREEITEM CGroupList::FindVisGroupItemRecursive(HTREEITEM hItem, CVisGroup *pVisGroup)
  177. {
  178. if (hItem)
  179. {
  180. CVisGroup *pVisGroupCheck = (CVisGroup *)GetItemData(hItem);
  181. if (pVisGroupCheck == pVisGroup)
  182. {
  183. return hItem;
  184. }
  185. if (ItemHasChildren(hItem))
  186. {
  187. HTREEITEM hChildItem = GetChildItem(hItem);
  188. while (hChildItem != NULL)
  189. {
  190. HTREEITEM hFoundItem = FindVisGroupItemRecursive(hChildItem, pVisGroup);
  191. if (hFoundItem)
  192. {
  193. return hFoundItem;
  194. }
  195. hChildItem = GetNextItem(hChildItem, TVGN_NEXT);
  196. }
  197. }
  198. }
  199. return NULL;
  200. }
  201. //-----------------------------------------------------------------------------
  202. // Purpose: Returns the tree item associated with the given visgroup, NULL if none.
  203. //-----------------------------------------------------------------------------
  204. HTREEITEM CGroupList::FindVisGroupItem(CVisGroup *pVisGroup)
  205. {
  206. HTREEITEM hItem = GetRootItem();
  207. while (hItem)
  208. {
  209. HTREEITEM hFound = FindVisGroupItemRecursive(hItem, pVisGroup);
  210. if (hFound)
  211. {
  212. return hFound;
  213. }
  214. hItem = GetNextItem(hItem, TVGN_NEXT);
  215. }
  216. return NULL;
  217. }
  218. //-----------------------------------------------------------------------------
  219. // Purpose: Returns the currently selected visgroup in the tree control.
  220. //-----------------------------------------------------------------------------
  221. CVisGroup *CGroupList::GetSelectedVisGroup(void)
  222. {
  223. HTREEITEM hItem = GetSelectedItem();
  224. if (hItem)
  225. {
  226. return (CVisGroup *)GetItemData(hItem);
  227. }
  228. return NULL;
  229. }
  230. //-----------------------------------------------------------------------------
  231. // Purpose:
  232. // Input : nFlags -
  233. // point -
  234. //-----------------------------------------------------------------------------
  235. void CGroupList::OnLButtonDown(UINT nFlags, CPoint point)
  236. {
  237. unsigned int uFlags;
  238. HTREEITEM hItemHit = HitTest(point, &uFlags);
  239. if (hItemHit != NULL)
  240. {
  241. if (uFlags & TVHT_ONITEMICON)
  242. {
  243. // Don't forward to the base if they clicked on the check box.
  244. // This prevents undesired expansion/collapse of tree.
  245. return;
  246. }
  247. }
  248. CTreeCtrl::OnLButtonDown(nFlags, point);
  249. }
  250. //-----------------------------------------------------------------------------
  251. // Purpose:
  252. // Input : nFlags -
  253. // point -
  254. //-----------------------------------------------------------------------------
  255. void CGroupList::OnLButtonUp(UINT nFlags, CPoint point)
  256. {
  257. KillTimer(TIMER_GROUP_DRAG_SCROLL);
  258. ReleaseCapture();
  259. if (!m_hDragItem)
  260. {
  261. unsigned int uFlags;
  262. HTREEITEM hItemHit = HitTest(point, &uFlags);
  263. if (hItemHit != NULL)
  264. {
  265. if (uFlags & TVHT_ONITEMICON)
  266. {
  267. //
  268. // Notify our parent window that this item's state has changed.
  269. //
  270. CWnd *pwndParent = GetParent();
  271. if (pwndParent != NULL)
  272. {
  273. int nCheckState = GetCheck(hItemHit);
  274. if (!nCheckState)
  275. {
  276. nCheckState = 1;
  277. }
  278. else
  279. {
  280. nCheckState = 0;
  281. }
  282. CVisGroup *pGroup = (CVisGroup *)GetItemData(hItemHit);
  283. pwndParent->PostMessage(g_uToggleStateMsg, (WPARAM)pGroup, nCheckState);
  284. }
  285. // Don't forward to the base if they clicked on the check box.
  286. // This prevents undesired expansion/collapse of tree.
  287. return;
  288. }
  289. }
  290. CTreeCtrl::OnLButtonUp(nFlags, point);
  291. return;
  292. }
  293. Drop(DROP_LEFT, nFlags, point);
  294. }
  295. //-----------------------------------------------------------------------------
  296. // Purpose:
  297. // Input : nFlags -
  298. // point -
  299. //-----------------------------------------------------------------------------
  300. void CGroupList::OnLButtonDblClk(UINT nFlags, CPoint point)
  301. {
  302. unsigned int uFlags;
  303. HTREEITEM hItemHit = HitTest(point, &uFlags);
  304. if (hItemHit != NULL)
  305. {
  306. if (uFlags & TVHT_ONITEMICON)
  307. {
  308. // Don't forward to the base if they clicked on the check box.
  309. // This prevents undesired expansion/collapse of tree.
  310. return;
  311. }
  312. }
  313. CTreeCtrl::OnLButtonDblClk(nFlags, point);
  314. }
  315. //-----------------------------------------------------------------------------
  316. // Purpose: Forwards selection change notifications to our parent window.
  317. // Input : pNMHDR -
  318. // pResult -
  319. //-----------------------------------------------------------------------------
  320. void CGroupList::OnSelChange(NMHDR *pNMHDR, LRESULT *pResult)
  321. {
  322. CWnd *pwndParent = GetParent();
  323. if (pwndParent != NULL)
  324. {
  325. pwndParent->PostMessage(g_uSelChangeMsg, 0, 0);
  326. }
  327. }
  328. //-----------------------------------------------------------------------------
  329. // Purpose:
  330. // Input : pNMHDR -
  331. // pResult -
  332. //-----------------------------------------------------------------------------
  333. void CGroupList::OnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult)
  334. {
  335. NMTVDISPINFO *pInfo = (NMTVDISPINFO *)pNMHDR;
  336. if (!pInfo->item.pszText)
  337. return;
  338. CVisGroup *pVisGroup = (CVisGroup *)GetItemData(pInfo->item.hItem);
  339. Assert(pVisGroup);
  340. if (!pVisGroup)
  341. return;
  342. pVisGroup->SetName(pInfo->item.pszText);
  343. pResult[0] = TRUE;
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Purpose: Begins dragging an item in the visgroup list. The drag image is
  347. // created and anchored relative to the mouse cursor.
  348. // Input : pNMHDR -
  349. // pResult -
  350. //-----------------------------------------------------------------------------
  351. void CGroupList::OnBegindrag(NMHDR *pNMHDR, LRESULT *pResult)
  352. {
  353. NMTREEVIEW *ptv = (NMTREEVIEW *)pNMHDR;
  354. BeginDrag(ptv->ptDrag, ptv->itemNew.hItem);
  355. *pResult = 0;
  356. }
  357. //-----------------------------------------------------------------------------
  358. // Purpose:
  359. // Input : pt -
  360. // hItem -
  361. //-----------------------------------------------------------------------------
  362. void CGroupList::BeginDrag(CPoint point, HTREEITEM hItem)
  363. {
  364. m_hDragItem = hItem;
  365. if (m_hDragItem)
  366. {
  367. m_pDragImageList = CreateDragImage(m_hDragItem);
  368. if (m_pDragImageList)
  369. {
  370. CPoint ptHotSpot(0, 0);
  371. m_pDragImageList->BeginDrag(0, ptHotSpot);
  372. m_pDragImageList->DragEnter(this, point);
  373. SelectDropTarget(NULL);
  374. }
  375. // Timer handles scrolling the list control when dragging outside the window bounds.
  376. SetTimer(TIMER_GROUP_DRAG_SCROLL, 300, NULL);
  377. SetCapture();
  378. }
  379. }
  380. //-----------------------------------------------------------------------------
  381. // Purpose:
  382. // Input : nFlags -
  383. // point -
  384. //-----------------------------------------------------------------------------
  385. void CGroupList::OnRButtonDown(UINT nFlags, CPoint point)
  386. {
  387. m_bRButtonDown = true;
  388. m_ptRButtonDown = point;
  389. m_hDragItem = NULL;
  390. SetCapture();
  391. // Chaining to the base class causes us never to receive the button up message
  392. // for a right click without drag, so we don't do that.
  393. //CTreeCtrl::OnRButtonDown(nFlags, point);
  394. }
  395. //-----------------------------------------------------------------------------
  396. // Purpose:
  397. // Input : pWnd -
  398. // point -
  399. //-----------------------------------------------------------------------------
  400. void CGroupList::OnContextMenu(CWnd *pWnd, CPoint point)
  401. {
  402. KillTimer(TIMER_GROUP_DRAG_SCROLL);
  403. ReleaseCapture();
  404. m_bRButtonDown = false;
  405. if (!m_hDragItem)
  406. {
  407. CTreeCtrl::OnContextMenu(pWnd, point);
  408. return;
  409. }
  410. Drop(DROP_RIGHT, 0, point);
  411. }
  412. //-----------------------------------------------------------------------------
  413. // Purpose:
  414. // Input : nFlags -
  415. // point -
  416. //-----------------------------------------------------------------------------
  417. void CGroupList::OnRButtonUp(UINT nFlags, CPoint point)
  418. {
  419. KillTimer(TIMER_GROUP_DRAG_SCROLL);
  420. ReleaseCapture();
  421. m_bRButtonDown = false;
  422. if (!m_hDragItem)
  423. {
  424. CTreeCtrl::OnRButtonUp(nFlags, point);
  425. return;
  426. }
  427. Drop(DROP_RIGHT, nFlags, point);
  428. }
  429. //-----------------------------------------------------------------------------
  430. // Purpose:
  431. // Input : eDropType -
  432. // nFlags -
  433. // point -
  434. //-----------------------------------------------------------------------------
  435. void CGroupList::Drop(DropType_t eDropType, UINT nFlags, CPoint point)
  436. {
  437. SelectDropTarget(NULL);
  438. HTREEITEM hDragItem = m_hDragItem;
  439. m_hDragItem = NULL;
  440. //
  441. // We are dragging. Drop!
  442. //
  443. if (m_pDragImageList)
  444. {
  445. m_pDragImageList->DragLeave(this);
  446. m_pDragImageList->EndDrag();
  447. delete m_pDragImageList;
  448. m_pDragImageList = NULL;
  449. }
  450. //
  451. // Get the group that we were dragging.
  452. //
  453. CVisGroup *pDragGroup = (CVisGroup *)GetItemData(hDragItem);
  454. //
  455. // Determine what group was dropped onto.
  456. //
  457. HTREEITEM hDropItem = HitTest(point);
  458. if (hDropItem == hDragItem)
  459. {
  460. return;
  461. }
  462. CVisGroup *pDropGroup = NULL;
  463. if (hDropItem)
  464. {
  465. pDropGroup = (CVisGroup *)GetItemData(hDropItem);
  466. }
  467. if (pDragGroup == pDropGroup)
  468. {
  469. // Shouldn't happen, but just in case.
  470. return;
  471. }
  472. CWnd *pwndParent = GetParent();
  473. if (pwndParent != NULL)
  474. {
  475. if (eDropType == DROP_LEFT)
  476. {
  477. pwndParent->PostMessage(g_uLeftDragDropMsg, (WPARAM)pDragGroup, (LPARAM)pDropGroup);
  478. }
  479. else
  480. {
  481. pwndParent->PostMessage(g_uRightDragDropMsg, (WPARAM)pDragGroup, (LPARAM)pDropGroup);
  482. }
  483. }
  484. }
  485. //-----------------------------------------------------------------------------
  486. // Purpose:
  487. // Input : nIDEvent -
  488. //-----------------------------------------------------------------------------
  489. void CGroupList::OnTimer(UINT nIDEvent)
  490. {
  491. //DBG("OnTimer\n");
  492. switch (nIDEvent)
  493. {
  494. case TIMER_GROUP_DRAG_SCROLL:
  495. {
  496. CPoint point;
  497. GetCursorPos(&point);
  498. CRect rect;
  499. GetWindowRect(&rect);
  500. if (!rect.PtInRect(point))
  501. {
  502. if (point.y > rect.bottom)
  503. {
  504. // scroll down
  505. int nCount = GetVisibleCount();
  506. HTREEITEM hItem = GetFirstVisibleItem();
  507. for (int i = 1; i < nCount; i++)
  508. {
  509. hItem = GetNextVisibleItem(hItem);
  510. }
  511. hItem = GetNextVisibleItem(hItem);
  512. if (hItem)
  513. {
  514. CTreeCtrl::EnsureVisible(hItem);
  515. }
  516. }
  517. else if (point.y < rect.top)
  518. {
  519. HTREEITEM hItem = GetFirstVisibleItem();
  520. HTREEITEM hPrevVisible = this->GetPrevVisibleItem(hItem);
  521. if (hPrevVisible)
  522. {
  523. // scroll up
  524. CTreeCtrl::EnsureVisible(hPrevVisible);
  525. }
  526. }
  527. }
  528. break;
  529. }
  530. default:
  531. {
  532. CTreeCtrl::OnTimer(nIDEvent);
  533. }
  534. }
  535. }
  536. //-----------------------------------------------------------------------------
  537. // Purpose:
  538. // Input : nFlags -
  539. // point -
  540. //-----------------------------------------------------------------------------
  541. void CGroupList::OnMouseMove(UINT nFlags, CPoint point)
  542. {
  543. CTreeCtrl::OnMouseMove(nFlags, point);
  544. if (m_bRButtonDown && !m_hDragItem && (point.x != m_ptRButtonDown.x) && (point.y != m_ptRButtonDown.y))
  545. {
  546. // First mouse move since a right button down. Start dragging.
  547. HTREEITEM hItem = HitTest(m_ptRButtonDown);
  548. BeginDrag(point, hItem);
  549. }
  550. if (!m_hDragItem)
  551. {
  552. return;
  553. }
  554. if (m_pDragImageList)
  555. {
  556. m_pDragImageList->DragMove(point);
  557. }
  558. //
  559. // Highlight the item we hit.
  560. //
  561. HTREEITEM hItem = HitTest(point);
  562. if (hItem == GetDropHilightItem())
  563. {
  564. return;
  565. }
  566. // hide image first
  567. if (m_pDragImageList)
  568. {
  569. m_pDragImageList->DragLeave(this);
  570. m_pDragImageList->DragShowNolock(FALSE);
  571. }
  572. SelectDropTarget(hItem);
  573. if (m_pDragImageList)
  574. {
  575. m_pDragImageList->DragEnter(this, point);
  576. }
  577. }
  578. //-----------------------------------------------------------------------------
  579. // Purpose:
  580. //-----------------------------------------------------------------------------
  581. void CGroupList::SelectVisGroup(CVisGroup *pVisGroup)
  582. {
  583. //DBG("SelectVisGroup: %s\n", pVisGroup->GetName());
  584. HTREEITEM hItem = FindVisGroupItem(pVisGroup);
  585. if (hItem)
  586. {
  587. Select(hItem, TVGN_CARET);
  588. }
  589. }
  590. //-----------------------------------------------------------------------------
  591. // Purpose: Sets the check status for the given group.
  592. // Input : pVisGroup -
  593. // nCheckState - 0=not checked, 1=checked, -1=gray check (undefined)
  594. //-----------------------------------------------------------------------------
  595. void CGroupList::SetCheck(CVisGroup *pVisGroup, int nCheckState)
  596. {
  597. HTREEITEM hItem = FindVisGroupItem(pVisGroup);
  598. if (hItem)
  599. {
  600. UINT uState = INDEXTOOVERLAYMASK(0);
  601. if (nCheckState == 1)
  602. {
  603. uState = INDEXTOOVERLAYMASK(1);
  604. }
  605. else if (nCheckState != 0)
  606. {
  607. uState = INDEXTOOVERLAYMASK(2);
  608. }
  609. SetItemState(hItem, uState, TVIS_OVERLAYMASK);
  610. }
  611. }
  612. //-----------------------------------------------------------------------------
  613. // Purpose: Returns the check state for the given visgroup.
  614. // Input : pVisGroup -
  615. //-----------------------------------------------------------------------------
  616. int CGroupList::GetCheck(CVisGroup *pVisGroup)
  617. {
  618. HTREEITEM hItem = FindVisGroupItem(pVisGroup);
  619. if (hItem)
  620. {
  621. return GetCheck(hItem);
  622. }
  623. return 0;
  624. }
  625. //-----------------------------------------------------------------------------
  626. // Purpose:
  627. //-----------------------------------------------------------------------------
  628. int CGroupList::GetCheck(HTREEITEM hItem)
  629. {
  630. UINT uState = (GetItemState(hItem, TVIS_OVERLAYMASK) & TVIS_OVERLAYMASK);
  631. if (uState == INDEXTOOVERLAYMASK(1))
  632. {
  633. return 1;
  634. }
  635. else if (uState == INDEXTOOVERLAYMASK(0))
  636. {
  637. return 0;
  638. }
  639. return -1;
  640. }
  641. //-----------------------------------------------------------------------------
  642. // Purpose: Returns the number of visgroups in the whole tree.
  643. //-----------------------------------------------------------------------------
  644. int CGroupList::GetVisGroupCount()
  645. {
  646. return m_VisGroups.Count();
  647. }
  648. //-----------------------------------------------------------------------------
  649. // Purpose:
  650. //-----------------------------------------------------------------------------
  651. CVisGroup *CGroupList::GetVisGroup(int nIndex)
  652. {
  653. return m_VisGroups.Element(nIndex);
  654. }
  655. //-----------------------------------------------------------------------------
  656. // Purpose: Updates the tree control item text with the new group name.
  657. //-----------------------------------------------------------------------------
  658. void CGroupList::UpdateVisGroup(CVisGroup *pVisGroup)
  659. {
  660. HTREEITEM hItem = FindVisGroupItem(pVisGroup);
  661. if (hItem)
  662. {
  663. SetItemText(hItem, pVisGroup->GetName());
  664. }
  665. }
  666. int CGroupList::GetGroupPairCount(void)
  667. {
  668. return m_GroupPairs.Count();
  669. }
  670. void CGroupList::SaveVisGroupExpandStates()
  671. {
  672. for ( int i = 0; i < GetVisGroupCount(); i++ )
  673. {
  674. CVisGroup *thisGroup = GetVisGroup(i);
  675. GroupListPair newPair;
  676. for ( int j = 0; j < GetGroupPairCount(); j++ )
  677. {
  678. GroupListPair thisPair = m_GroupPairs.Element( j );
  679. if ( thisGroup == thisPair.pVisGroup )
  680. {
  681. m_GroupPairs.Remove( j );
  682. break;
  683. }
  684. }
  685. HTREEITEM thisItem = FindVisGroupItem( thisGroup );
  686. newPair.pVisGroup = thisGroup;
  687. newPair.bExpanded = false;
  688. if ( thisItem && (GetItemState( thisItem, TVIS_EXPANDED) & TVIS_EXPANDED) )
  689. {
  690. newPair.bExpanded = true;
  691. }
  692. m_GroupPairs.AddToTail( newPair );
  693. }
  694. }
  695. void CGroupList::RestoreVisGroupExpandStates()
  696. {
  697. ExpandAll();
  698. for ( int i = 0; i < GetGroupPairCount(); i++ )
  699. {
  700. GroupListPair thisPair = m_GroupPairs.Element( i );
  701. HTREEITEM thisItem = FindVisGroupItem( thisPair.pVisGroup );
  702. if ( thisItem )
  703. {
  704. if ( thisPair.bExpanded )
  705. {
  706. Expand(thisItem, TVE_EXPAND);
  707. }
  708. else
  709. {
  710. Expand( thisItem, TVE_COLLAPSE );
  711. }
  712. }
  713. }
  714. }