[poincare] Stop edition if a matrix cannot add an additional row/column

This commit is contained in:
Léa Saviot
2018-07-27 14:04:00 +02:00
parent 0677f4935f
commit 8f41ca9942
4 changed files with 50 additions and 35 deletions

View File

@@ -108,6 +108,7 @@ public:
// TODO: put private
virtual bool willAddChildAtIndex(LayoutNode * l, int * index, LayoutCursor * cursor) { return true; }
virtual bool willAddSibling(LayoutCursor * cursor, LayoutNode * sibling, bool moveCursor) { return true; }
virtual void willAddSiblingToEmptyChildAtIndex(int childIndex) {}
virtual bool willReplaceChild(LayoutNode * oldChild, LayoutNode * newChild, LayoutCursor * cursor, bool force);
virtual void didReplaceChildAtIndex(int index, LayoutCursor * cursor, bool force) {}
virtual bool willRemoveChild(LayoutNode * l, LayoutCursor * cursor, bool force);

View File

@@ -13,13 +13,13 @@ public:
using GridLayoutNode::GridLayoutNode;
// MatrixLayoutNode
void newRowOrColumnAtIndex(int index);
void addGreySquares();
void removeGreySquares();
// LayoutNode
void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) override;
void moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) override;
void willAddSiblingToEmptyChildAtIndex(int childIndex) override;
bool isMatrix() const override { return true; }
// SerializableNode
@@ -37,11 +37,11 @@ protected:
// LayoutNode
void computeSize() override;
KDPoint positionOfChild(LayoutNode * l) override;
void moveCursorVertically(VerticalDirection direction, LayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) override;
void moveCursorVertically(VerticalDirection direction, LayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) override;
private:
// MatrixNode
void childWasReplacedAtIndex(int index);
void newRowOrColumnAtIndex(int index);
bool isRowEmpty(int index) const;
bool isColumnEmpty(int index) const;
bool hasGreySquares() const;

View File

@@ -77,10 +77,19 @@ bool EmptyLayoutNode::willAddSibling(LayoutCursor * cursor, LayoutNode * sibling
* being filled in, so add a new empty row or column. */
LayoutNode * parentNode = parent();
assert(parentNode != nullptr);
static_cast<MatrixLayoutNode *>(parentNode)->newRowOrColumnAtIndex(parentNode->indexOfChild(this));
// WARNING: Do not use "this" afterwards.
LayoutRef parentRef(parentNode);
parentNode->willAddSiblingToEmptyChildAtIndex(parentRef.indexOfChild(thisRef));
// WARNING: Do not use previous node pointers afterwards.
bool shouldContinueAddition = !(parentRef.isAllocationFailure());
if (!shouldContinueAddition) {
if (moveCursor) {
cursor->setLayoutReference(parentRef);
}
return false;
}
}
if (sibling->mustHaveLeftSibling()) {
if (siblingRef.mustHaveLeftSibling()) {
thisRef.setColor(Color::Yellow);
return true;
} else {

View File

@@ -8,35 +8,6 @@ namespace Poincare {
// MatrixLayoutNode
void MatrixLayoutNode::newRowOrColumnAtIndex(int index) {
assert(index >= 0 && index < m_numberOfColumns*m_numberOfRows);
bool shouldAddNewRow = childIsBottomOfGrid(index); // We need to compute this boolean before modifying the layout
int correspondingRow = rowAtChildIndex(index);
if (childIsRightOfGrid(index)) {
// Color the grey EmptyLayouts of the column in yellow.
int correspondingColumn = m_numberOfColumns - 1;
for (int i = 0; i < m_numberOfRows - 1; i++) {
LayoutNode * lastLayoutOfRow = childAtIndex(i*m_numberOfColumns+correspondingColumn);
if (lastLayoutOfRow->isEmpty()) {
static_cast<EmptyLayoutNode *>(lastLayoutOfRow)->setColor(EmptyLayoutNode::Color::Yellow);
}
}
// Add a column of grey EmptyLayouts on the right.
addEmptyColumn(EmptyLayoutNode::Color::Grey);
}
if (shouldAddNewRow) {
// Color the grey EmptyLayouts of the row in yellow.
for (int i = 0; i < m_numberOfColumns - 1; i++) {
LayoutNode * lastLayoutOfColumn = childAtIndex(correspondingRow*m_numberOfColumns+i);
if (lastLayoutOfColumn->isEmpty()) {
static_cast<EmptyLayoutNode *>(lastLayoutOfColumn)->setColor(EmptyLayoutNode::Color::Yellow);
}
}
// Add a row of grey EmptyLayouts at the bottom.
addEmptyRow(EmptyLayoutNode::Color::Grey);
}
}
void MatrixLayoutNode::addGreySquares() {
if (!hasGreySquares()) {
addEmptyRow(EmptyLayoutNode::Color::Grey);
@@ -113,6 +84,11 @@ void MatrixLayoutNode::moveCursorRight(LayoutCursor * cursor, bool * shouldRecom
GridLayoutNode::moveCursorRight(cursor, shouldRecomputeLayout);
}
void MatrixLayoutNode::willAddSiblingToEmptyChildAtIndex(int childIndex) {
if (childIsRightOfGrid(childIndex) || childIsBottomOfGrid(childIndex)) {
newRowOrColumnAtIndex(childIndex);
}
}
// SerializableNode
@@ -183,6 +159,35 @@ void MatrixLayoutNode::moveCursorVertically(VerticalDirection direction, LayoutC
// Private
void MatrixLayoutNode::newRowOrColumnAtIndex(int index) {
assert(index >= 0 && index < m_numberOfColumns*m_numberOfRows);
bool shouldAddNewRow = childIsBottomOfGrid(index); // We need to compute this boolean before modifying the layout
int correspondingRow = rowAtChildIndex(index);
if (childIsRightOfGrid(index)) {
// Color the grey EmptyLayouts of the column in yellow.
int correspondingColumn = m_numberOfColumns - 1;
for (int i = 0; i < m_numberOfRows - 1; i++) {
LayoutNode * lastLayoutOfRow = childAtIndex(i*m_numberOfColumns+correspondingColumn);
if (lastLayoutOfRow->isEmpty()) {
static_cast<EmptyLayoutNode *>(lastLayoutOfRow)->setColor(EmptyLayoutNode::Color::Yellow);
}
}
// Add a column of grey EmptyLayouts on the right.
addEmptyColumn(EmptyLayoutNode::Color::Grey);
}
if (shouldAddNewRow) {
// Color the grey EmptyLayouts of the row in yellow.
for (int i = 0; i < m_numberOfColumns - 1; i++) {
LayoutNode * lastLayoutOfColumn = childAtIndex(correspondingRow*m_numberOfColumns+i);
if (lastLayoutOfColumn->isEmpty()) {
static_cast<EmptyLayoutNode *>(lastLayoutOfColumn)->setColor(EmptyLayoutNode::Color::Yellow);
}
}
// Add a row of grey EmptyLayouts at the bottom.
addEmptyRow(EmptyLayoutNode::Color::Grey);
}
}
bool MatrixLayoutNode::isRowEmpty(int index) const {
assert(index >= 0 && index < m_numberOfRows);
for (int i = index * m_numberOfColumns; i < (index+1) * m_numberOfColumns; i++) {