From b4be993d2f3ebe6b11bba1283db5933e18a89fd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 17 Apr 2018 10:59:06 +0200 Subject: [PATCH] [poincare] Check children when moving vertically in HorizontalLayout Change-Id: Ib0fa5ef58b605c16079e46040a28c96695dcf3d5 --- poincare/src/layout/horizontal_layout.cpp | 36 ++++++++++++++++------- poincare/src/layout/horizontal_layout.h | 2 ++ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/poincare/src/layout/horizontal_layout.cpp b/poincare/src/layout/horizontal_layout.cpp index 29be089e5..aa0a30053 100644 --- a/poincare/src/layout/horizontal_layout.cpp +++ b/poincare/src/layout/horizontal_layout.cpp @@ -1,6 +1,5 @@ #include "horizontal_layout.h" #include "empty_layout.h" -#include extern "C" { #include #include @@ -424,18 +423,17 @@ bool HorizontalLayout::moveVertically(ExpressionLayout::VerticalDirection direct newPosition = ExpressionLayoutCursor::Position::Left; } if (brother && cursor->positionIsEquivalentTo(brother, newPosition)) { - ExpressionLayout * previousPointedLayout = cursor->pointedExpressionLayout(); - ExpressionLayoutCursor::Position previousPosition = cursor->position(); - cursor->setPointedExpressionLayout(brother); - cursor->setPosition(newPosition); - if (direction == ExpressionLayout::VerticalDirection::Up && brother->moveUp(cursor, shouldRecomputeLayout, this, previousLayout)) { + if (tryMoveVerticallyFromAnotherLayout(brother, newPosition, direction, cursor, shouldRecomputeLayout, previousLayout)) { return true; } - if (direction == ExpressionLayout::VerticalDirection::Down && brother->moveDown(cursor, shouldRecomputeLayout, this, previousLayout)) { - return true; - } - cursor->setPointedExpressionLayout(previousPointedLayout); - cursor->setPosition(previousPosition); + } + } + /* If the cursor is Lefit or Right of the HorizontalLayout, try moving it up + * from its extremal child. */ + if (cursor->pointedExpressionLayout() == this && previousLayout == nullptr) { + int indexOfChildToCheck = cursor->position() == ExpressionLayoutCursor::Position::Left ? 0 : numberOfChildren() - 1; + if (tryMoveVerticallyFromAnotherLayout(editableChild(indexOfChildToCheck), cursor->position(), direction, cursor, shouldRecomputeLayout, previousLayout)) { + return true; } } if (direction == ExpressionLayout::VerticalDirection::Up) { @@ -445,6 +443,22 @@ bool HorizontalLayout::moveVertically(ExpressionLayout::VerticalDirection direct return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } +bool HorizontalLayout::tryMoveVerticallyFromAnotherLayout(ExpressionLayout * otherLayout, ExpressionLayoutCursor::Position otherPosition, ExpressionLayout::VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout) { + ExpressionLayout * previousPointedLayout = cursor->pointedExpressionLayout(); + ExpressionLayoutCursor::Position previousPosition = cursor->position(); + cursor->setPointedExpressionLayout(otherLayout); + cursor->setPosition(otherPosition); + if (direction == ExpressionLayout::VerticalDirection::Up && otherLayout->moveUp(cursor, shouldRecomputeLayout, this, previousLayout)) { + return true; + } + if (direction == ExpressionLayout::VerticalDirection::Down && otherLayout->moveDown(cursor, shouldRecomputeLayout, this, previousLayout)) { + return true; + } + cursor->setPointedExpressionLayout(previousPointedLayout); + cursor->setPosition(previousPosition); + return false; +} + void HorizontalLayout::privateRemoveChildAtIndex(int index, bool deleteAfterRemoval, bool forceRemove) { // If the child to remove is at index 0 and its right brother must have a left // brother (e.g. it is a VerticalOffsetLayout), replace the child with an diff --git a/poincare/src/layout/horizontal_layout.h b/poincare/src/layout/horizontal_layout.h index f194d5376..d69cd0daf 100644 --- a/poincare/src/layout/horizontal_layout.h +++ b/poincare/src/layout/horizontal_layout.h @@ -3,6 +3,7 @@ #include #include +#include namespace Poincare { @@ -48,6 +49,7 @@ protected: void privateAddBrother(ExpressionLayoutCursor * cursor, ExpressionLayout * brother, bool moveCursor) override; private: bool moveVertically(ExpressionLayout::VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout); + bool tryMoveVerticallyFromAnotherLayout(ExpressionLayout * otherLayout, ExpressionLayoutCursor::Position otherPosition, ExpressionLayout::VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout); void privateReplaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor); void privateRemoveChildAtIndex(int index, bool deleteAfterRemoval, bool forceRemove); int removeEmptyChildBeforeInsertionAtIndex(int index, bool shouldRemoveOnLeft);