mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-29 11:39:58 +02:00
[poincare] LayoutReference::deleteBeforeCursor
This commit is contained in:
@@ -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; }
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -17,6 +17,7 @@ TreeNode * LayoutRef::FailedAllocationStaticNode() {
|
||||
return &FailureNode;
|
||||
}
|
||||
|
||||
// Cursor
|
||||
template <typename T>
|
||||
LayoutCursor LayoutReference<T>::cursor() const {
|
||||
return LayoutCursor(this->typedNode());
|
||||
|
||||
Reference in New Issue
Block a user