#include "StdAfx.h" #include "TreeView.h" namespace ui { TreeNode::TreeNode() : m_bExpand(true), m_pTreeView(nullptr), m_pParentTreeNode(nullptr), m_iDepth(ROOT_NODE_DEPTH), m_aTreeNodes() { } bool TreeNode::IsVisible() const { return ListContainerElement::IsVisible() && (!m_pParentTreeNode || (m_pParentTreeNode && m_pParentTreeNode->IsExpand() && m_pParentTreeNode->IsVisible())); } void TreeNode::SetInternVisible(bool bVisible) { Control::SetInternVisible(bVisible); if (m_items.empty()) return; for (auto it = m_items.begin(); it != m_items.end(); it++) { auto pControl = *it; // 控制子控件显示状态 // InternVisible状态应由子控件自己控制 pControl->SetInternVisible(Control::IsVisible()); } } void TreeNode::SetWindow(Window* pManager, Box* pParent, bool bInit) { for (auto it = m_aTreeNodes.begin(); it != m_aTreeNodes.end(); it++) { (*it)->SetWindow(pManager, this, bInit); } ListContainerElement::SetWindow(pManager, pParent, bInit); } void TreeNode::SetTreeView(TreeView* pTreeView) { m_pTreeView = pTreeView; } bool TreeNode::OnClickItem(EventArgs* pMsg) { TreeNode* pItem = static_cast(pMsg->pSender); pItem->SetExpand(!pItem->IsExpand()); return true; } TreeNode* TreeNode::GetParentNode() { return m_pParentTreeNode; } void TreeNode::SetParentNode(TreeNode* pParentTreeNode) { m_pParentTreeNode = pParentTreeNode; } bool TreeNode::AddChildNode(TreeNode* pTreeNode) { return AddChildNodeAt(pTreeNode, GetChildNodeCount()); } bool TreeNode::AddChildNodeAt(TreeNode* pTreeNode, std::size_t iIndex) { if( iIndex < 0 || iIndex > m_aTreeNodes.size() ) return false; m_aTreeNodes.insert(m_aTreeNodes.begin() + iIndex, pTreeNode); pTreeNode->m_iDepth = m_iDepth + 1; pTreeNode->SetParentNode(this); pTreeNode->SetTreeView(m_pTreeView); if( m_pWindow != NULL ) m_pWindow->InitControls(pTreeNode, NULL); pTreeNode->OnEvent[kEventClick] += nbase::Bind(&TreeNode::OnClickItem, this, std::placeholders::_1); UiRect padding = m_pLayout->GetPadding(); int nodeIndex = -1; if (m_iDepth != ROOT_NODE_DEPTH) { nodeIndex = GetIndex(); padding.left += m_pTreeView->GetIndent(); } pTreeNode->m_pLayout->SetPadding(padding); std::size_t nGlobalIndex = iIndex; for (std::size_t i = 0; i < iIndex; i++) { nGlobalIndex += ((TreeNode*)m_aTreeNodes[i])->GetDescendantNodeCount(); } return m_pTreeView->ListBox::AddAt(pTreeNode, (int)(nodeIndex + nGlobalIndex + 1)); } bool TreeNode::RemoveChildNodeAt(std::size_t iIndex) { if (iIndex < 0 || iIndex >= m_aTreeNodes.size()) { return false; } TreeNode* pTreeNode = ((TreeNode*)m_aTreeNodes[iIndex]); m_aTreeNodes.erase(m_aTreeNodes.begin() + iIndex); return pTreeNode->RemoveSelf(); } bool TreeNode::RemoveChildNode(TreeNode* pTreeNode) { auto it = std::find(m_aTreeNodes.begin(), m_aTreeNodes.end(), pTreeNode); if (it == m_aTreeNodes.end()) { return false; } int iIndex = it - m_aTreeNodes.begin(); return RemoveChildNodeAt(iIndex); } void TreeNode::RemoveAllChildNode() { while (m_aTreeNodes.size() > 0) { RemoveChildNodeAt(0); } } bool TreeNode::RemoveSelf() { for( auto it = m_aTreeNodes.begin(); it != m_aTreeNodes.end(); it++ ) { (*it)->RemoveSelf(); } m_aTreeNodes.clear(); if (m_iDepth != ROOT_NODE_DEPTH) { return m_pTreeView->ListBox::RemoveAt(GetIndex()); } return false; } int TreeNode::GetDescendantNodeCount() { int nodeCount = (int)GetChildNodeCount(); for( auto it = m_aTreeNodes.begin(); it != m_aTreeNodes.end(); it++ ) { nodeCount += (*it)->GetDescendantNodeCount(); } return nodeCount; } std::size_t TreeNode::GetChildNodeCount() { return m_aTreeNodes.size(); } TreeNode* TreeNode::GetChildNode(std::size_t iIndex) { if( iIndex < 0 || iIndex >= m_aTreeNodes.size() ) return NULL; return static_cast(m_aTreeNodes[iIndex]); } int TreeNode::GetChildNodeIndex(TreeNode* pTreeNode) { auto it = std::find(m_aTreeNodes.begin(), m_aTreeNodes.end(), pTreeNode); if (it == m_aTreeNodes.end()) { return -1; } return it - m_aTreeNodes.begin(); } bool TreeNode::IsExpand() const { return m_bExpand; } void TreeNode::SetExpand(bool bExpand) { if(m_bExpand == bExpand) { return; } m_bExpand = bExpand; m_pTreeView->Arrange(); } int TreeNode::GetDepth() { return m_iDepth; } TreeView::TreeView() : ListBox(new VLayout), m_iIndent(0), m_rootNode() { m_rootNode.reset(new TreeNode()); m_rootNode->SetTreeView(this); } void TreeView::SetAttribute(const std::wstring& strName, const std::wstring& strValue) { if( strName == _T("indent") ) { SetIndent(_ttoi(strValue.c_str())); } else { ListBox::SetAttribute(strName, strValue); } } bool TreeView::Add(Control* pControl) { ASSERT(FALSE); return true; } bool TreeView::AddAt(Control* pControl, std::size_t iIndex) { ASSERT(FALSE); return true; } bool TreeView::Remove(Control* pControl) { ASSERT(FALSE); return true; } bool TreeView::RemoveAt(std::size_t iIndex) { ASSERT(FALSE); return true; } void TreeView::RemoveAll() { ASSERT(FALSE); } void TreeView::SetWindow(Window* pManager, Box* pParent, bool bInit) { ListBox::SetWindow(pManager, pParent, bInit); if (NULL != pParent) m_rootNode->SetWindow(pManager, pParent, bInit); } }