From 48e20abe73f828c21772fffdcff387fa806ecd2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Fri, 22 Dec 2017 13:28:16 +0100 Subject: [PATCH] [poincare] Navigation and delete in GridLayout. Change-Id: I8357150d9f15dd003ab97e09981d164d57235739 --- poincare/src/layout/expression_layout.cpp | 3 ++- poincare/src/layout/grid_layout.cpp | 31 ++++++++++++++++++++--- poincare/src/layout/grid_layout.h | 1 + poincare/src/layout/horizontal_layout.cpp | 12 +++++++++ poincare/src/layout/horizontal_layout.h | 1 + 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/poincare/src/layout/expression_layout.cpp b/poincare/src/layout/expression_layout.cpp index 5fdae5833..3b5bc8316 100644 --- a/poincare/src/layout/expression_layout.cpp +++ b/poincare/src/layout/expression_layout.cpp @@ -127,7 +127,8 @@ bool ExpressionLayout::hasAncestor(const ExpressionLayout * e) const { void ExpressionLayout::addBrother(ExpressionLayoutCursor * cursor, ExpressionLayout * brother) { if (m_parent) { int brotherIndex = cursor->position() == ExpressionLayoutCursor::Position::Left ? m_parent->indexOfChild(this) : m_parent->indexOfChild(this) + 1; - if (m_parent->addChildAtIndex(brother, brotherIndex)) { + if (m_parent->isHorizontal()) { + m_parent->addChildAtIndex(brother, brotherIndex); return; } if (cursor->position() == ExpressionLayoutCursor::Position::Left) { diff --git a/poincare/src/layout/grid_layout.cpp b/poincare/src/layout/grid_layout.cpp index 9821533de..2ad50f177 100644 --- a/poincare/src/layout/grid_layout.cpp +++ b/poincare/src/layout/grid_layout.cpp @@ -1,4 +1,5 @@ #include "grid_layout.h" +#include "empty_visible_layout.h" #include extern "C" { #include @@ -19,6 +20,30 @@ ExpressionLayout * GridLayout::clone() const { return layout; } +void GridLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { + // If the cursor is on the left of the grid, delete the grid and its parent: A + // grid only exists for now in binomial coefficient and in matrices, and we + // want to delete their parentheses or brackets too. + if (cursor->position() == ExpressionLayoutCursor::Position::Left) { + int indexOfPointedExpression = indexOfChild(cursor->pointedExpressionLayout()); + if (indexOfPointedExpression >= 0 && childIsLeftOfGrid(indexOfPointedExpression)) { + assert(m_parent != nullptr); + assert(m_parent->parent() != nullptr); + ExpressionLayout * grandParent = const_cast(m_parent->parent()); + int indexInGrandParent = grandParent->indexOfChild(m_parent); + m_parent->replaceWith(new EmptyVisibleLayout(), true); + if (indexInGrandParent == 0) { + cursor->setPointedExpressionLayout(grandParent); + return; + } + cursor->setPointedExpressionLayout(grandParent->editableChild(indexInGrandParent-1)); + cursor->setPosition(ExpressionLayoutCursor::Position::Right); + return; + } + } + ExpressionLayout::backspaceAtCursor(cursor); +} + bool GridLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Case: Right. // Go to the last entry. @@ -38,7 +63,7 @@ bool GridLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Go Left of the grid cursor->setPointedExpressionLayout(this); cursor->setPosition(ExpressionLayoutCursor::Position::Left); - return true; + return m_parent->moveLeft(cursor); } // Case: Left of another child. // Go Right of its brother on the left. @@ -72,10 +97,10 @@ bool GridLayout::moveRight(ExpressionLayoutCursor * cursor) { if (childIndex >- 1 && cursor->position() == ExpressionLayoutCursor::Position::Right) { if (childIsRightOfGrid(childIndex)) { // Case: Right of a child on the right of the grid. - // Go Right of the grid. + // Go Right of the grid and move Right. cursor->setPointedExpressionLayout(this); cursor->setPosition(ExpressionLayoutCursor::Position::Right); - return true; + return m_parent->moveRight(cursor); } // Case: Right of another child. // Go Left of its brother on the right. diff --git a/poincare/src/layout/grid_layout.h b/poincare/src/layout/grid_layout.h index 379fd642f..e2275511b 100644 --- a/poincare/src/layout/grid_layout.h +++ b/poincare/src/layout/grid_layout.h @@ -9,6 +9,7 @@ class GridLayout : public DynamicLayoutHierarchy { public: GridLayout(ExpressionLayout ** entryLayouts, int numberOfRows, int numberOfColumns, bool cloneOperands); ExpressionLayout * clone() const override; + void backspaceAtCursor(ExpressionLayoutCursor * cursor) override; /* Navigation */ bool moveLeft(ExpressionLayoutCursor * cursor) override; diff --git a/poincare/src/layout/horizontal_layout.cpp b/poincare/src/layout/horizontal_layout.cpp index 303fb23db..38d125e6c 100644 --- a/poincare/src/layout/horizontal_layout.cpp +++ b/poincare/src/layout/horizontal_layout.cpp @@ -15,6 +15,18 @@ ExpressionLayout * HorizontalLayout::clone() const { return layout; } +void HorizontalLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { + // If the cursor was pointing left of the first child of the horizontal + // layout, make it point at the horizontal layout itself. + if (cursor->position() == ExpressionLayoutCursor::Position::Left) { + int indexOfPointedExpression = indexOfChild(cursor->pointedExpressionLayout()); + if (indexOfPointedExpression == 0) { + cursor->setPointedExpressionLayout(this); + } + } + ExpressionLayout::backspaceAtCursor(cursor); +} + void HorizontalLayout::replaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild) { if (newChild->isEmpty()) { if (numberOfChildren() > 1) { diff --git a/poincare/src/layout/horizontal_layout.h b/poincare/src/layout/horizontal_layout.h index 7c58113b9..a3aef1244 100644 --- a/poincare/src/layout/horizontal_layout.h +++ b/poincare/src/layout/horizontal_layout.h @@ -9,6 +9,7 @@ class HorizontalLayout : public DynamicLayoutHierarchy { public: using DynamicLayoutHierarchy::DynamicLayoutHierarchy; ExpressionLayout * clone() const override; + void backspaceAtCursor(ExpressionLayoutCursor * cursor) override; /* Hierarchy */ void replaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild = true) override;