void JObjectTree::DropNode( JObject* pNode, JObject* pDest, bool bAsChild, bool bClone ) { if (!pNode || !pDest) return; JObject* pAddedNode = pNode; pNode->AddRef(); if (bClone) { const char* nodeName = pNode->GetName(); pAddedNode = pNode->Clone( NULL, nodeName ); } else { pNode->GetParent()->RemoveChild( pNode ); } if (!bAsChild) { // insert after the node we dropped onto JObject* pParent = pDest->GetParent(); pParent->AddChild( pAddedNode, pParent->GetChildIndex( pDest ) + 1 ); } else { // add as child node pDest->AddChild( pAddedNode ); } pNode->Release(); } // JObjectTree::DropNode
void JObjectTree::Traverse( TraverseCallback callback, void* pContext ) const { if (!m_pRoot) return; float nodeW = m_NodeWidth; float nodeVisH = m_NodeHeight; Frame ext( m_RootPos.x, m_RootPos.y, nodeW, nodeVisH ); // find node path for tree expansion static std::vector<int> nodePath; nodePath.clear(); JObject* pCurObj = m_pExpanded; if (pCurObj) nodePath.push_back( 0 ); while (pCurObj && pCurObj != m_pRoot) { JObject* pParent = pCurObj->GetParent(); if (!pParent) break; nodePath.push_back( pParent->GetChildIndex( pCurObj ) ); pCurObj = pParent; } // traverse root node (which is never collapsed) if ((this->*callback)( ext, m_pRoot, (m_pExpanded != NULL), pContext ) == false) return; // traverse along expansion path pCurObj = m_pRoot; for (int i = nodePath.size() - 1; i >= 0; i--) { int childIdx = nodePath[i]; if (!pCurObj) break; int nCh = pCurObj->GetNChildren(); if (childIdx >= nCh) break; float blockH = float( nCh )*nodeVisH; ext.y = ext.y - blockH*0.5f + nodeVisH*0.5f; ext.x += nodeW; float cY = ext.y; for (int j = 0; j < nCh; j++) { JObject* pChild = pCurObj->GetChild( j ); Frame chExt( ext ); chExt.y = cY; bool bExpanded = (j == childIdx)&&(pCurObj != m_pExpanded); if ((this->*callback)( chExt, pChild, bExpanded, pContext ) == false) { return; } cY += nodeVisH; } pCurObj = pCurObj->GetChild( childIdx ); ext.y += float( childIdx )*nodeVisH; } } // JObjectTree::Traverse
bool JObjectTree::DeleteNode() { if (!m_pSelected) return false; JObject* pParent = m_pSelected->GetParent(); if (!pParent) return false; int idx = pParent->GetChildIndex( m_pSelected ); pParent->RemoveChild( m_pSelected ); if (idx >= pParent->GetNChildren()) idx = pParent->GetNChildren() - 1; if (idx < 0) idx = 0; m_pSelected = pParent->GetChild( idx ); if (!m_pSelected) m_pSelected = pParent; m_pExpanded = m_pSelected; return true; } // JObjectTree::DeleteNode