//------------------------------------------------------------------------------ u32 Entity::removeChild(Entity * child) { u32 i = indexOfChild(child); if (i != m_children.size()) removeChildAtIndex(i); return i; }
void OctreeTests::elementAddChildTests() { EntityTreePointer tree = std::make_shared<EntityTree>(); auto elem = tree->createNewElement(); QCOMPARE((bool)elem->getChildAtIndex(0), false); elem->addChildAtIndex(0); QCOMPARE((bool)elem->getChildAtIndex(0), true); const int MAX_CHILD_INDEX = 8; for (int i = 0; i < MAX_CHILD_INDEX; i++) { for (int j = 0; j < MAX_CHILD_INDEX; j++) { auto e = tree->createNewElement(); // add a single child. auto firstChild = e->addChildAtIndex(i); QCOMPARE(e->getChildAtIndex(i), firstChild); if (i != j) { // add a second child. auto secondChild = e->addChildAtIndex(j); QCOMPARE(e->getChildAtIndex(i), firstChild); QCOMPARE(e->getChildAtIndex(j), secondChild); // remove scecond child. e->removeChildAtIndex(j); QCOMPARE((bool)e->getChildAtIndex(j), false); } QCOMPARE(e->getChildAtIndex(i), firstChild); } } }
void HorizontalLayout::privateReplaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor) { bool oldWasAncestorOfNewLayout = false; if (newChild->hasAncestor(this)) { newChild->editableParent()->detachChild(newChild); oldWasAncestorOfNewLayout = true; } int oldChildIndex = indexOfChild(oldChild); if (newChild->isEmpty()) { if (numberOfChildren() > 1) { /* If the new layout is empty and the horizontal layout has other * children, just delete the old child. */ if (!newChild->hasAncestor(oldChild)) { delete newChild; } removeChildAtIndex(oldChildIndex, deleteOldChild); if (cursor == nullptr) { return; } if (oldChildIndex == 0) { cursor->setPointedExpressionLayout(this); cursor->setPosition(ExpressionLayoutCursor::Position::Left); return; } cursor->setPointedExpressionLayout(editableChild(oldChildIndex -1)); cursor->setPosition(ExpressionLayoutCursor::Position::Right); return; } /* If the new layout is empty and it was the only horizontal layout child, * replace the horizontal layout with this empty layout (only if this is not * the main layout, so only if the layout has a parent). */ if (m_parent) { if (!deleteOldChild) { removeChildAtIndex(indexOfChild(oldChild), false); } if (cursor) { replaceWithAndMoveCursor(newChild, true, cursor); return; } replaceWith(newChild, deleteOldChild); return; } /* If this is the main horizontal layout, the old child its only child and * the new child is Empty, remove the old child and delete the new child. */ assert(m_parent == nullptr); removeChildAtIndex(0, deleteOldChild); delete newChild; if (cursor == nullptr) { return; } cursor->setPointedExpressionLayout(this); cursor->setPosition(ExpressionLayoutCursor::Position::Left); return; } /* If the new child is also an horizontal layout, steal the children of the * new layout then destroy it. */ if (newChild->isHorizontal()) { int indexForInsertion = indexOfChild(oldChild); if (cursor != nullptr) { /* If the old layout is not an ancestor of the new layout, or if the * cursor was on the right of the new layout, place the cursor on the * right of the new layout, which is left of the next sibling or right of * the parent. */ if (!oldWasAncestorOfNewLayout || cursor->position() == ExpressionLayoutCursor::Position::Right) { if (oldChildIndex == numberOfChildren() - 1) { cursor->setPointedExpressionLayout(this); cursor->setPosition(ExpressionLayoutCursor::Position::Right); } else { cursor->setPointedExpressionLayout(editableChild(oldChildIndex + 1)); cursor->setPosition(ExpressionLayoutCursor::Position::Left); } } else { /* Else place the cursor on the left of the new layout, which is right * of the previous sibling or left of the parent. */ if (oldChildIndex == 0) { cursor->setPointedExpressionLayout(this); cursor->setPosition(ExpressionLayoutCursor::Position::Left); } else { cursor->setPointedExpressionLayout(editableChild(oldChildIndex - 1)); cursor->setPosition(ExpressionLayoutCursor::Position::Right); } } } bool oldChildRemovedAtMerge = oldChild->isEmpty(); mergeChildrenAtIndex(static_cast<HorizontalLayout *>(newChild), indexForInsertion + 1, true); if (!oldChildRemovedAtMerge) { removeChildAtIndex(indexForInsertion, deleteOldChild); } return; } // Else, just replace the child. if (cursor != nullptr && !oldWasAncestorOfNewLayout) { cursor->setPosition(ExpressionLayoutCursor::Position::Right); } ExpressionLayout::replaceChild(oldChild, newChild, deleteOldChild); if (cursor == nullptr) { return; } cursor->setPointedExpressionLayout(newChild); }