[poincare] Detach layouts before adding them

This commit is contained in:
Léa Saviot
2018-08-07 16:26:28 +02:00
parent 267b16a768
commit dab15bd52d
6 changed files with 52 additions and 14 deletions

View File

@@ -73,8 +73,18 @@ void BracketPairLayoutNode::moveCursorRight(LayoutCursor * cursor, bool * should
void BracketPairLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) {
if (cursor->isEquivalentTo(LayoutCursor(childLayout(), LayoutCursor::Position::Left))) {
// Case: Left of the operand. Delete the layout, keep the operand.
LayoutRef(this).replaceWith(LayoutRef(childLayout()), cursor);
LayoutRef rootRef = LayoutRef(root());
LayoutRef thisRef = LayoutRef(this);
LayoutRef child = childLayout();
replaceChildWithGhostInPlace(child);
// WARNING: do not call "this" afterwards
if (rootRef.isAllocationFailure()) {
cursor->setLayoutReference(rootRef);
return;
}
cursor->setLayoutReference(thisRef.childAtIndex(0));
cursor->setPosition(LayoutNode::Position::Left);
thisRef.replaceWith(child, cursor);
return;
}
LayoutNode::deleteBeforeCursor(cursor);

View File

@@ -109,16 +109,10 @@ void FractionLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) {
* is right of the numerator. */
LayoutRef numeratorRef = LayoutRef(numeratorLayout());
LayoutRef denominatorRef = LayoutRef(denominatorLayout());
thisRef.replaceChild(numeratorRef, EmptyLayoutRef());
if (thisRef.isAllocationFailure()) {
return;
}
thisRef.replaceChild(denominatorRef, EmptyLayoutRef());
if (thisRef.isAllocationFailure()) {
return;
}
thisRef.replaceWithJuxtapositionOf(numeratorRef, denominatorRef, cursor, true);
thisRef.replaceChildWithGhostInPlace(numeratorRef);
// WARNING: Do no use "this" afterwards
thisRef.replaceChildWithGhostInPlace(denominatorRef);
thisRef.replaceWithJuxtapositionOf(numeratorRef, denominatorRef, cursor, true);
return;
}

View File

@@ -132,8 +132,18 @@ void IntegralLayoutNode::moveCursorDown(LayoutCursor * cursor, bool * shouldReco
void IntegralLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) {
if (cursor->isEquivalentTo(LayoutCursor(integrandLayout(), LayoutCursor::Position::Left))) {
// Case: Left of the integrand. Delete the layout, keep the integrand.
LayoutRef(this).replaceWith(LayoutRef(integrandLayout()), cursor);
LayoutRef rootRef = LayoutRef(root());
LayoutRef thisRef = LayoutRef(this);
LayoutRef integrand = LayoutRef(integrandLayout());
thisRef.replaceChildWithGhostInPlace(integrand);
// WARNING: Do not use "this" afterwards
if (rootRef.isAllocationFailure()) {
cursor->setLayoutReference(rootRef);
return;
}
cursor->setLayoutReference(thisRef.childAtIndex(0));
cursor->setPosition(LayoutCursor::Position::Left);
thisRef.replaceWith(integrand, cursor);
return;
}
LayoutNode::deleteBeforeCursor(cursor);

View File

@@ -139,8 +139,17 @@ void NthRootLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) {
&& cursor->position() == LayoutCursor::Position::Left)
{
// Case: Left of the radicand. Delete the layout, keep the radicand.
NthRootLayoutRef(this).replaceWith(LayoutRef(radicandLayout()), cursor);
LayoutRef radicand = LayoutRef(radicandLayout());
LayoutRef thisRef = LayoutRef(this);
LayoutRef rootRef = LayoutRef(root());
thisRef.replaceChildWithGhostInPlace(radicand);
// WARNING: Do not call "this" afterwards
if (rootRef.isAllocationFailure()) {
cursor->setLayoutReference(rootRef);
return;
}
cursor->setLayoutReference(thisRef.childAtIndex(0));
thisRef.replaceWith(radicand, cursor);
return;
}
LayoutNode::deleteBeforeCursor(cursor);

View File

@@ -119,8 +119,17 @@ void SequenceLayoutNode::moveCursorDown(LayoutCursor * cursor, bool * shouldReco
void SequenceLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) {
if (cursor->isEquivalentTo(LayoutCursor(argumentLayout(), LayoutCursor::Position::Left))) {
// Case: Left of the argument. Delete the layout, keep the argument.
LayoutRef(this).replaceWith(LayoutRef(argumentLayout()), cursor);
// WARNING: do not use "this" afterwards
LayoutRef argument = LayoutRef(argumentLayout());
LayoutRef thisRef = LayoutRef(this);
LayoutRef rootRef = LayoutRef(root());
thisRef.replaceChildWithGhostInPlace(argument);
// WARNING: Do not call "this" afterwards
if (rootRef.isAllocationFailure()) {
cursor->setLayoutReference(rootRef);
return;
}
cursor->setLayoutReference(thisRef.childAtIndex(0));
thisRef.replaceWith(argument, cursor);
return;
}
LayoutNode::deleteBeforeCursor(cursor);

View File

@@ -32,6 +32,9 @@ TreeByReference TreeByReference::clone() const {
void TreeByReference::replaceWithInPlace(TreeByReference t) {
assert(isDefined());
if (isAllocationFailure()) {
return;
}
TreeByReference p = parent();
if (p.isDefined()) {
p.replaceChildInPlace(*this, t);
@@ -44,6 +47,9 @@ void TreeByReference::replaceChildInPlace(TreeByReference oldChild, TreeByRefere
}
assert(isDefined());
if (isAllocationFailure()) {
return;
}
if (newChild.isAllocationFailure()) {
replaceWithAllocationFailureInPlace(numberOfChildren());
return;