[poincare] LayoutReference::deleteBeforeCursor

This commit is contained in:
Léa Saviot
2018-07-05 14:26:44 +02:00
parent 93f07c1fb8
commit 8a3be2bac3
7 changed files with 107 additions and 1 deletions

View File

@@ -17,8 +17,11 @@ public:
m_numberOfChildren(0)
{}
// Tree modification
void addOrMergeChildAtIndex(LayoutNode * l, int index, bool removeEmptyChildren);
void mergeChildrenAtIndex(HorizontalLayoutNode * horizontalLayout, int index, bool removeEmptyChildren);
void deleteBeforeCursor(LayoutCursor * cursor) override;
void removeChildAndMoveCursor(LayoutNode * l, LayoutCursor * cursor) override;
// LayoutNode
bool isHorizontal() const override { return true; }

View File

@@ -108,9 +108,11 @@ public:
void addEmptySquarePowerLayout() {} //TODO
void addEmptyTenPowerLayout() {} //TODO
void addEmptyMatrixLayout() {} //TODO
void performBackspace() {} //TODO
bool showEmptyLayoutIfNeeded() { return false; } //TODO
bool hideEmptyLayoutIfNeeded() { return false; } //TODO
void performBackspace() {
m_layoutRef.deleteBeforeCursor(this);
}
void insertText(const char * text);
void addLayoutAndMoveCursor(LayoutRef l);
void clearLayout();

View File

@@ -71,6 +71,8 @@ public:
// Tree modification
void addSibling(LayoutCursor * cursor, LayoutNode * sibling);
void addSiblingAndMoveCursor(LayoutCursor * cursor, LayoutNode * sibling);
virtual void removeChildAndMoveCursor(LayoutNode * l, LayoutCursor * cursor);
virtual void deleteBeforeCursor(LayoutCursor * cursor);
void collapseSiblingsAndMoveCursor(LayoutCursor * cursor) {} //TODO
bool removeGreySquaresFromAllMatrixAncestors() { return false; } //TODO
bool addGreySquaresToAllMatrixAncestors() { return false; } //TODO

View File

@@ -46,6 +46,7 @@ public:
char XNTChar() const { return this->typedNode()->XNTChar(); }
// Layout modification
void deleteBeforeCursor(LayoutCursor * cursor) { return this->typedNode()->deleteBeforeCursor(cursor); }
bool removeGreySquaresFromAllMatrixAncestors() { return this->typedNode()->removeGreySquaresFromAllMatrixAncestors(); }
bool addGreySquaresToAllMatrixAncestors() { return this->typedNode()->addGreySquaresToAllMatrixAncestors(); }
LayoutReference<LayoutNode> layoutToPointWhenInserting() { return LayoutReference<LayoutNode>(this->typedNode()->layoutToPointWhenInserting()); }
@@ -68,6 +69,7 @@ public:
}
void addSibling(LayoutCursor * cursor, LayoutReference<LayoutNode> sibling) { return this->typedNode()->addSibling(cursor, sibling.typedNode()); }
void addSiblingAndMoveCursor(LayoutCursor * cursor, LayoutReference<LayoutNode> sibling) { return this->typedNode()->addSiblingAndMoveCursor(cursor, sibling.typedNode()); }
void removeChildAndMoveCursor(LayoutReference<LayoutNode> l, LayoutCursor * cursor) { return this->typedNode()->removeChildAndMoveCursor(l.typedNode(), cursor); }
void collapseSiblingsAndMoveCursor(LayoutCursor * cursor) {} //TODO
LayoutReference<LayoutNode> replaceWithJuxtapositionOf(LayoutReference<LayoutNode> leftChild, LayoutReference<LayoutNode> rightChild); //TODO

View File

@@ -25,6 +25,60 @@ void HorizontalLayoutNode::mergeChildrenAtIndex(HorizontalLayoutNode * h, int in
LayoutRef(this).mergeChildrenAtIndex(LayoutRef(h), newIndex);
}
void HorizontalLayoutNode::deleteBeforeCursor(LayoutCursor * cursor) {
LayoutNode * p = parent();
if (p == nullptr
&& cursor->layoutReference().node() == this
&& (cursor->position() == LayoutCursor::Position::Left
|| numberOfChildren() == 0))
{
/* Case: Left and this is the main layout or Right and this is the main
* layout with no children. Return. */
return;
}
if (cursor->position() == LayoutCursor::Position::Left) {
int indexOfPointedLayout = indexOfChild(cursor->layoutReference().typedNode());
if (indexOfPointedLayout >= 0) {
/* Case: Left of a child.
* Point Right of the previous child. If there is no previous child, point
* Left of this. Perform another backspace. */
if (indexOfPointedLayout == 0) {
cursor->setLayoutNode(this);
} else {
assert(indexOfPointedLayout > 0);
cursor->setLayoutNode(childAtIndex(indexOfPointedLayout - 1));
cursor->setPosition(LayoutCursor::Position::Right);
}
cursor->performBackspace();
return;
}
}
assert(cursor->layoutReference().node() == this);
if (cursor->position() == LayoutCursor::Position::Right) {
// Case: Right. Point to the last child and perform backspace.
cursor->setLayoutNode(childAtIndex(numberOfChildren() - 1));
cursor->performBackspace();
return;
}
LayoutNode::deleteBeforeCursor(cursor);
}
void HorizontalLayoutNode::removeChildAndMoveCursor(LayoutNode * l, LayoutCursor * cursor) {
if (numberOfChildren() == 1) {
assert(childAtIndex(0) == l);
LayoutNode * p = parent();
if (p != nullptr) {
p->removeChildAndMoveCursor(this, cursor);
} else {
removeChild(l);
cursor->setLayoutNode(this);
cursor->setPosition(LayoutCursor::Position::Left);
}
return;
}
LayoutNode::removeChildAndMoveCursor(l, cursor);
}
int HorizontalLayoutNode::writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits) const {
if (numberOfChildren() == 0) {
if (bufferSize == 0) {

View File

@@ -81,6 +81,48 @@ void LayoutNode::addSiblingAndMoveCursor(LayoutCursor * cursor, LayoutNode * sib
privateAddSibling(cursor, sibling, true);
}
void LayoutNode::removeChildAndMoveCursor(LayoutNode * l, LayoutCursor * cursor) {
assert(hasChild(l));
int index = indexOfChild(l);
removeChild(l);
if (index < numberOfChildren()) {
cursor->setLayoutNode(childAtIndex(index));
cursor->setPosition(LayoutCursor::Position::Left);
} else {
int newPointedLayoutIndex = index - 1;
assert(newPointedLayoutIndex >= 0);
assert(newPointedLayoutIndex < numberOfChildren());
cursor->setLayoutNode(childAtIndex(newPointedLayoutIndex));
cursor->setPosition(LayoutCursor::Position::Right);
}
}
void LayoutNode::deleteBeforeCursor(LayoutCursor * cursor) {
int indexOfPointedLayout = indexOfChild(cursor->layoutReference().typedNode());
if (indexOfPointedLayout >= 0) {
// Case: The pointed layout is a child. Move Left.
assert(cursor->position() == LayoutCursor::Position::Left);
bool shouldRecomputeLayout = false;
cursor->moveLeft(&shouldRecomputeLayout);
return;
}
assert(cursor->layoutReference().node() == this);
LayoutNode * p = parent();
// Case: this is the pointed layout.
if (p == nullptr) {
// Case: No parent. Return.
return;
}
if (cursor->position() == LayoutCursor::Position::Left) {
// Case: Left. Ask the parent.
p->deleteBeforeCursor(cursor);
return;
}
assert(cursor->position() == LayoutCursor::Position::Right);
// Case: Right. Delete the layout.
p->removeChildAndMoveCursor(this, cursor);
}
// Private
void LayoutNode::privateAddSibling(LayoutCursor * cursor, LayoutNode * sibling, bool moveCursor) {

View File

@@ -17,6 +17,7 @@ TreeNode * LayoutRef::FailedAllocationStaticNode() {
return &FailureNode;
}
// Cursor
template <typename T>
LayoutCursor LayoutReference<T>::cursor() const {
return LayoutCursor(this->typedNode());