diff --git a/escher/include/escher/editable_expression_view.h b/escher/include/escher/editable_expression_view.h index f4cf92423..84dcd8d9b 100644 --- a/escher/include/escher/editable_expression_view.h +++ b/escher/include/escher/editable_expression_view.h @@ -30,6 +30,7 @@ public: protected: virtual bool privateHandleEvent(Ion::Events::Event event); + bool privateHandleMoveEvent(Ion::Events::Event event, bool * shouldRecomputeLayout); ExpressionViewWithCursor m_expressionViewWithCursor; private: EditableExpressionViewDelegate * m_delegate; diff --git a/escher/src/editable_expression_view.cpp b/escher/src/editable_expression_view.cpp index 01159a81a..acc66f38d 100644 --- a/escher/src/editable_expression_view.cpp +++ b/escher/src/editable_expression_view.cpp @@ -31,6 +31,21 @@ Toolbox * EditableExpressionView::toolbox() { bool EditableExpressionView::handleEvent(Ion::Events::Event event) { KDSize previousSize = minimalSizeForOptimalDisplay(); + bool shouldRecomputeLayout = false; + if (privateHandleMoveEvent(event, &shouldRecomputeLayout)) { + if (!shouldRecomputeLayout) { + m_expressionViewWithCursor.cursorPositionChanged(); + scrollToCursor(); + return true; + } + reload(); + KDSize newSize = minimalSizeForOptimalDisplay(); + if (m_delegate && previousSize.height() != newSize.height()) { + m_delegate->editableExpressionViewDidChangeSize(this); + reload(); + } + return true; + } if (privateHandleEvent(event)) { reload(); KDSize newSize = minimalSizeForOptimalDisplay(); @@ -51,6 +66,32 @@ KDSize EditableExpressionView::minimalSizeForOptimalDisplay() const { return m_expressionViewWithCursor.minimalSizeForOptimalDisplay(); } +bool EditableExpressionView::privateHandleMoveEvent(Ion::Events::Event event, bool * shouldRecomputeLayout) { + if (event == Ion::Events::Left) { + return m_expressionViewWithCursor.cursor()->moveLeft(shouldRecomputeLayout); + } + if (event == Ion::Events::Right) { + return m_expressionViewWithCursor.cursor()->moveRight(shouldRecomputeLayout); + } + if (event == Ion::Events::Up) { + return m_expressionViewWithCursor.cursor()->moveUp(shouldRecomputeLayout); + } + if (event == Ion::Events::Down) { + return m_expressionViewWithCursor.cursor()->moveDown(shouldRecomputeLayout); + } + if (event == Ion::Events::ShiftLeft) { + m_expressionViewWithCursor.cursor()->setPointedExpressionLayout(m_expressionViewWithCursor.expressionView()->expressionLayout()); + m_expressionViewWithCursor.cursor()->setPosition(Poincare::ExpressionLayoutCursor::Position::Left); + return true; + } + if (event == Ion::Events::ShiftRight) { + m_expressionViewWithCursor.cursor()->setPointedExpressionLayout(m_expressionViewWithCursor.expressionView()->expressionLayout()); + m_expressionViewWithCursor.cursor()->setPosition(Poincare::ExpressionLayoutCursor::Position::Right); + return true; + } + return false; +} + bool EditableExpressionView::privateHandleEvent(Ion::Events::Event event) { if (m_delegate && m_delegate->editableExpressionViewDidReceiveEvent(this, event)) { return true; @@ -76,28 +117,6 @@ bool EditableExpressionView::privateHandleEvent(Ion::Events::Event event) { } return true; } - if (event == Ion::Events::Left) { - return m_expressionViewWithCursor.cursor()->moveLeft(); - } - if (event == Ion::Events::Right) { - return m_expressionViewWithCursor.cursor()->moveRight(); - } - if (event == Ion::Events::Up) { - return m_expressionViewWithCursor.cursor()->moveUp(); - } - if (event == Ion::Events::Down) { - return m_expressionViewWithCursor.cursor()->moveDown(); - } - if (event == Ion::Events::ShiftLeft) { - m_expressionViewWithCursor.cursor()->setPointedExpressionLayout(m_expressionViewWithCursor.expressionView()->expressionLayout()); - m_expressionViewWithCursor.cursor()->setPosition(Poincare::ExpressionLayoutCursor::Position::Left); - return true; - } - if (event == Ion::Events::ShiftRight) { - m_expressionViewWithCursor.cursor()->setPointedExpressionLayout(m_expressionViewWithCursor.expressionView()->expressionLayout()); - m_expressionViewWithCursor.cursor()->setPosition(Poincare::ExpressionLayoutCursor::Position::Right); - return true; - } if (event == Ion::Events::Division) { m_expressionViewWithCursor.cursor()->addFractionLayoutAndCollapseBrothers(); return true; diff --git a/poincare/include/poincare/expression_layout.h b/poincare/include/poincare/expression_layout.h index 43992af35..580f89273 100644 --- a/poincare/include/poincare/expression_layout.h +++ b/poincare/include/poincare/expression_layout.h @@ -75,18 +75,20 @@ public: virtual void backspaceAtCursor(ExpressionLayoutCursor * cursor); /* Tree navigation */ - virtual bool moveLeft(ExpressionLayoutCursor * cursor) = 0; - virtual bool moveRight(ExpressionLayoutCursor * cursor) = 0; + virtual bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) = 0; + virtual bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) = 0; virtual bool moveUp( ExpressionLayoutCursor * cursor, + bool * shouldRecomputeLayout = nullptr, ExpressionLayout * previousLayout = nullptr, ExpressionLayout * previousPreviousLayout = nullptr); virtual bool moveDown( ExpressionLayoutCursor * cursor, + bool * shouldRecomputeLayout = nullptr, ExpressionLayout * previousLayout = nullptr, ExpressionLayout * previousPreviousLayout = nullptr); - virtual bool moveUpInside(ExpressionLayoutCursor * cursor); - virtual bool moveDownInside(ExpressionLayoutCursor * cursor); + virtual bool moveUpInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr); + virtual bool moveDownInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr); /* Expression Engine */ virtual int writeTextInBuffer(char * buffer, int bufferSize) const = 0; @@ -119,6 +121,13 @@ protected: virtual KDSize computeSize() = 0; virtual void computeBaseline() = 0; virtual KDPoint positionOfChild(ExpressionLayout * child) = 0; + virtual void moveCursorInsideAtDirection ( + VerticalDirection direction, + ExpressionLayoutCursor * cursor, + bool * shouldRecomputeLayout, + ExpressionLayout ** childResult, + void * resultPosition, + int * resultScore); ExpressionLayout * m_parent; KDCoordinate m_baseline; /* m_baseline is the signed vertical distance from the top of the layout to @@ -129,13 +138,7 @@ protected: bool m_positioned; private: void detachChildAtIndex(int i); - bool moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor); - void moveCursorInsideAtDirection ( - VerticalDirection direction, - ExpressionLayoutCursor * cursor, - ExpressionLayout ** childResult, - void * resultPosition, - int * resultScore); + bool moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout); ExpressionLayout * replaceWithJuxtapositionOf(ExpressionLayout * leftChild, ExpressionLayout * rightChild, bool deleteAfterReplace); KDRect m_frame; }; diff --git a/poincare/include/poincare/expression_layout_cursor.h b/poincare/include/poincare/expression_layout_cursor.h index 5cfd89e4a..7145d3c81 100644 --- a/poincare/include/poincare/expression_layout_cursor.h +++ b/poincare/include/poincare/expression_layout_cursor.h @@ -33,10 +33,10 @@ public: KDPoint middleLeftPointOfCursor(ExpressionLayout * expressionLayout, Position position); /* Move */ - bool moveLeft(); - bool moveRight(); - bool moveUp(); - bool moveDown(); + bool moveLeft(bool * shouldRecomputeLayout = nullptr); + bool moveRight(bool * shouldRecomputeLayout); + bool moveUp(bool * shouldRecomputeLayout); + bool moveDown(bool * shouldRecomputeLayout); /* Edition */ void addLayout(ExpressionLayout * layout); diff --git a/poincare/src/expression_layout_cursor.cpp b/poincare/src/expression_layout_cursor.cpp index 87f5de8bb..0923f888e 100644 --- a/poincare/src/expression_layout_cursor.cpp +++ b/poincare/src/expression_layout_cursor.cpp @@ -25,20 +25,20 @@ KDPoint ExpressionLayoutCursor::middleLeftPointOfCursor(ExpressionLayout * expre return KDPoint(layoutOrigin.x() + expressionLayout->size().width(), y); } -bool ExpressionLayoutCursor::moveLeft() { - return m_pointedExpressionLayout->moveLeft(this); +bool ExpressionLayoutCursor::moveLeft(bool * shouldRecomputeLayout) { + return m_pointedExpressionLayout->moveLeft(this, shouldRecomputeLayout); } -bool ExpressionLayoutCursor::moveRight() { - return m_pointedExpressionLayout->moveRight(this); +bool ExpressionLayoutCursor::moveRight(bool * shouldRecomputeLayout) { + return m_pointedExpressionLayout->moveRight(this, shouldRecomputeLayout); } -bool ExpressionLayoutCursor::moveUp() { - return m_pointedExpressionLayout->moveUp(this); +bool ExpressionLayoutCursor::moveUp(bool * shouldRecomputeLayout) { + return m_pointedExpressionLayout->moveUp(this, shouldRecomputeLayout); } -bool ExpressionLayoutCursor::moveDown() { - return m_pointedExpressionLayout->moveDown(this); +bool ExpressionLayoutCursor::moveDown(bool * shouldRecomputeLayout) { + return m_pointedExpressionLayout->moveDown(this, shouldRecomputeLayout); } void ExpressionLayoutCursor::addLayout(ExpressionLayout * layout) { diff --git a/poincare/src/layout/binomial_coefficient_layout.cpp b/poincare/src/layout/binomial_coefficient_layout.cpp index aec65fd20..93867456a 100644 --- a/poincare/src/layout/binomial_coefficient_layout.cpp +++ b/poincare/src/layout/binomial_coefficient_layout.cpp @@ -18,7 +18,7 @@ ExpressionLayout * BinomialCoefficientLayout::clone() const { return new BinomialCoefficientLayout(const_cast(this)->nLayout(), const_cast(this)->kLayout(), true); } -bool BinomialCoefficientLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool BinomialCoefficientLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left of the children. // Go Left. if (cursor->position() == ExpressionLayoutCursor::Position::Left @@ -43,12 +43,12 @@ bool BinomialCoefficientLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Ask the parent. assert(cursor->position() == ExpressionLayoutCursor::Position::Left); if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool BinomialCoefficientLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool BinomialCoefficientLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right of the children. // Go Right. if (cursor->position() == ExpressionLayoutCursor::Position::Right @@ -71,27 +71,27 @@ bool BinomialCoefficientLayout::moveRight(ExpressionLayoutCursor * cursor) { // Case: Right. // Ask the parent. if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } -bool BinomialCoefficientLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool BinomialCoefficientLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // Case: kLayout. // Move to nLayout. if (previousLayout == kLayout()) { - return nLayout()->moveUpInside(cursor); + return nLayout()->moveUpInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } -bool BinomialCoefficientLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool BinomialCoefficientLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // Case: nLayout. // Move to kLayout. if (previousLayout == nLayout()) { - return kLayout()->moveDownInside(cursor); + return kLayout()->moveDownInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } void BinomialCoefficientLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) { diff --git a/poincare/src/layout/binomial_coefficient_layout.h b/poincare/src/layout/binomial_coefficient_layout.h index 30dc3da69..8cfa19323 100644 --- a/poincare/src/layout/binomial_coefficient_layout.h +++ b/poincare/src/layout/binomial_coefficient_layout.h @@ -10,10 +10,10 @@ class BinomialCoefficientLayout : public StaticLayoutHierarchy<2> { public: using StaticLayoutHierarchy::StaticLayoutHierarchy; ExpressionLayout * clone() const override; - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; - bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout = nullptr, ExpressionLayout * previousPreviousLayout = nullptr) override; - bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout = nullptr, ExpressionLayout * previousPreviousLayout = nullptr) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr, ExpressionLayout * previousLayout = nullptr, ExpressionLayout * previousPreviousLayout = nullptr) override; + bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr, ExpressionLayout * previousLayout = nullptr, ExpressionLayout * previousPreviousLayout = nullptr) override; int writeTextInBuffer(char * buffer, int bufferSize) const override { return LayoutEngine::writePrefixExpressionLayoutTextInBuffer(this, buffer, bufferSize, "binomial"); } diff --git a/poincare/src/layout/bracket_layout.cpp b/poincare/src/layout/bracket_layout.cpp index 38fd0b400..9fe511f88 100644 --- a/poincare/src/layout/bracket_layout.cpp +++ b/poincare/src/layout/bracket_layout.cpp @@ -25,7 +25,7 @@ void BracketLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { ExpressionLayout::backspaceAtCursor(cursor); } -bool BracketLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool BracketLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left of the operand. // Go Left of the brackets. if (operandLayout() @@ -47,12 +47,12 @@ bool BracketLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Case: Left of the brackets. // Ask the parent. if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool BracketLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool BracketLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right of the operand. // Go Right of the brackets. if (operandLayout() @@ -75,7 +75,7 @@ bool BracketLayout::moveRight(ExpressionLayoutCursor * cursor) { // Ask the parent. cursor->setPointedExpressionLayout(this); if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } diff --git a/poincare/src/layout/bracket_layout.h b/poincare/src/layout/bracket_layout.h index 94b63398f..b9a746f36 100644 --- a/poincare/src/layout/bracket_layout.h +++ b/poincare/src/layout/bracket_layout.h @@ -10,8 +10,8 @@ public: using StaticLayoutHierarchy::StaticLayoutHierarchy; ExpressionLayout * clone() const override; void backspaceAtCursor(ExpressionLayoutCursor * cursor) override; - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; int writeTextInBuffer(char * buffer, int bufferSize) const override; protected: ExpressionLayout * operandLayout(); diff --git a/poincare/src/layout/bracket_left_right_layout.cpp b/poincare/src/layout/bracket_left_right_layout.cpp index f39263fff..540a4ce89 100644 --- a/poincare/src/layout/bracket_left_right_layout.cpp +++ b/poincare/src/layout/bracket_left_right_layout.cpp @@ -18,7 +18,7 @@ void BracketLeftRightLayout::invalidAllSizesPositionsAndBaselines() { ExpressionLayout::invalidAllSizesPositionsAndBaselines(); } -bool BracketLeftRightLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool BracketLeftRightLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { assert(cursor->pointedExpressionLayout() == this); // Case: Right. // Go Left. @@ -30,12 +30,12 @@ bool BracketLeftRightLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Case: Left. // Ask the parent. if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool BracketLeftRightLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool BracketLeftRightLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { assert(cursor->pointedExpressionLayout() == this); // Case: Left. // Go Right. @@ -47,7 +47,7 @@ bool BracketLeftRightLayout::moveRight(ExpressionLayoutCursor * cursor) { // Case: Right. // Ask the parent. if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } diff --git a/poincare/src/layout/bracket_left_right_layout.h b/poincare/src/layout/bracket_left_right_layout.h index 98cf4e875..7dfc9708a 100644 --- a/poincare/src/layout/bracket_left_right_layout.h +++ b/poincare/src/layout/bracket_left_right_layout.h @@ -9,8 +9,8 @@ class BracketLeftRightLayout : public StaticLayoutHierarchy<0> { public: BracketLeftRightLayout(); void invalidAllSizesPositionsAndBaselines() override; - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; protected: constexpr static KDCoordinate k_bracketWidth = 5; constexpr static KDCoordinate k_lineThickness = 1; diff --git a/poincare/src/layout/char_layout.cpp b/poincare/src/layout/char_layout.cpp index b4e67dc52..0dde197c6 100644 --- a/poincare/src/layout/char_layout.cpp +++ b/poincare/src/layout/char_layout.cpp @@ -18,7 +18,7 @@ ExpressionLayout * CharLayout::clone() const { return layout; } -bool CharLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool CharLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { assert(cursor->pointedExpressionLayout() == this); // Case: Right. // Go Left. @@ -29,12 +29,12 @@ bool CharLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Case: Left. // Ask the parent. if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool CharLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool CharLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { assert(cursor->pointedExpressionLayout() == this); // Case: Left. // Go Right. @@ -45,7 +45,7 @@ bool CharLayout::moveRight(ExpressionLayoutCursor * cursor) { // Case: Right. // Ask the parent. if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } diff --git a/poincare/src/layout/char_layout.h b/poincare/src/layout/char_layout.h index cbdb775b8..37ebd3692 100644 --- a/poincare/src/layout/char_layout.h +++ b/poincare/src/layout/char_layout.h @@ -17,8 +17,8 @@ public: char character() { return m_char; } KDText::FontSize fontSize() const { return m_fontSize; } - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const override; protected: void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override; diff --git a/poincare/src/layout/condensed_sum_layout.cpp b/poincare/src/layout/condensed_sum_layout.cpp index a7a511e9e..33058438e 100644 --- a/poincare/src/layout/condensed_sum_layout.cpp +++ b/poincare/src/layout/condensed_sum_layout.cpp @@ -10,7 +10,7 @@ ExpressionLayout * CondensedSumLayout::clone() const { return layout; } -bool CondensedSumLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool CondensedSumLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left of the bounds. // Go Left of the sum. if (((subscriptLayout() && cursor->pointedExpressionLayout() == subscriptLayout()) @@ -37,18 +37,18 @@ bool CondensedSumLayout::moveLeft(ExpressionLayoutCursor * cursor) { if (cursor->position() == ExpressionLayoutCursor::Position::Right) { assert(baseLayout()); cursor->setPointedExpressionLayout(baseLayout()); - return baseLayout()->moveLeft(cursor); + return baseLayout()->moveLeft(cursor, shouldRecomputeLayout); } // Case: Left. // Ask the parent. assert(cursor->position() == ExpressionLayoutCursor::Position::Left); if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool CondensedSumLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool CondensedSumLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right of the bounds. // Go Left of the operand. if (((subscriptLayout() && cursor->pointedExpressionLayout() == subscriptLayout()) @@ -69,7 +69,7 @@ bool CondensedSumLayout::moveRight(ExpressionLayoutCursor * cursor) { cursor->setPointedExpressionLayout(this); cursor->setPosition(ExpressionLayoutCursor::Position::Right); if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } @@ -85,16 +85,16 @@ bool CondensedSumLayout::moveRight(ExpressionLayoutCursor * cursor) { // Ask the parent. assert(cursor->position() == ExpressionLayoutCursor::Position::Right); if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } -bool CondensedSumLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool CondensedSumLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is inside the subscript layout, move it to the superscript. if (subscriptLayout() && previousLayout == subscriptLayout()) { assert(superscriptLayout() != nullptr); - return superscriptLayout()->moveUpInside(cursor); + return superscriptLayout()->moveUpInside(cursor, shouldRecomputeLayout); } // If the cursor is Left of the base layout, move it to the superscript. if (baseLayout() @@ -102,16 +102,16 @@ bool CondensedSumLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayou && cursor->positionIsEquivalentTo(baseLayout(), ExpressionLayoutCursor::Position::Left)) { assert(superscriptLayout() != nullptr); - return superscriptLayout()->moveUpInside(cursor); + return superscriptLayout()->moveUpInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } -bool CondensedSumLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool CondensedSumLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is inside the superscript layout, move it to the subscript. if (superscriptLayout() && previousLayout == superscriptLayout()) { assert(subscriptLayout() != nullptr); - return subscriptLayout()->moveUpInside(cursor); + return subscriptLayout()->moveUpInside(cursor, shouldRecomputeLayout); } // If the cursor is Left of the base layout, move it to the subscript. if (baseLayout() @@ -119,9 +119,9 @@ bool CondensedSumLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLay && cursor->positionIsEquivalentTo(baseLayout(), ExpressionLayoutCursor::Position::Left)) { assert(subscriptLayout() != nullptr); - return subscriptLayout()->moveUpInside(cursor); + return subscriptLayout()->moveUpInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveDown(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } void CondensedSumLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) { diff --git a/poincare/src/layout/condensed_sum_layout.h b/poincare/src/layout/condensed_sum_layout.h index 2647474cd..d7a236e4e 100644 --- a/poincare/src/layout/condensed_sum_layout.h +++ b/poincare/src/layout/condensed_sum_layout.h @@ -10,10 +10,10 @@ class CondensedSumLayout : public StaticLayoutHierarchy<3> { public: using StaticLayoutHierarchy::StaticLayoutHierarchy; ExpressionLayout * clone() const override; - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; - bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; - bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; int writeTextInBuffer(char * buffer, int bufferSize) const override { return LayoutEngine::writePrefixExpressionLayoutTextInBuffer(this, buffer, bufferSize, "sum"); } diff --git a/poincare/src/layout/conjugate_layout.cpp b/poincare/src/layout/conjugate_layout.cpp index 7323e1fd7..15e90362d 100644 --- a/poincare/src/layout/conjugate_layout.cpp +++ b/poincare/src/layout/conjugate_layout.cpp @@ -27,7 +27,7 @@ void ConjugateLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { ExpressionLayout::backspaceAtCursor(cursor); } -bool ConjugateLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool ConjugateLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left of the operand. // Move Left. if (operandLayout() @@ -49,12 +49,12 @@ bool ConjugateLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Ask the parent. assert(cursor->position() == ExpressionLayoutCursor::Position::Left); if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool ConjugateLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool ConjugateLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right of the operand. // Move Right. if (operandLayout() @@ -76,7 +76,7 @@ bool ConjugateLayout::moveRight(ExpressionLayoutCursor * cursor) { // Ask the parent. assert(cursor->position() == ExpressionLayoutCursor::Position::Right); if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } diff --git a/poincare/src/layout/conjugate_layout.h b/poincare/src/layout/conjugate_layout.h index f4846619f..896e777a0 100644 --- a/poincare/src/layout/conjugate_layout.h +++ b/poincare/src/layout/conjugate_layout.h @@ -11,8 +11,8 @@ public: using StaticLayoutHierarchy::StaticLayoutHierarchy; ExpressionLayout * clone() const override; void backspaceAtCursor(ExpressionLayoutCursor * cursor) override; - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; void replaceChildAndMoveCursor(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor) override; void removePointedChildAtIndexAndMoveCursor(int index, bool deleteAfterRemoval, ExpressionLayoutCursor * cursor) override; int writeTextInBuffer(char * buffer, int bufferSize) const override { diff --git a/poincare/src/layout/empty_visible_layout.cpp b/poincare/src/layout/empty_visible_layout.cpp index bddbda688..5e8517611 100644 --- a/poincare/src/layout/empty_visible_layout.cpp +++ b/poincare/src/layout/empty_visible_layout.cpp @@ -40,7 +40,7 @@ void EmptyVisibleLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { } } -bool EmptyVisibleLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool EmptyVisibleLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { assert(cursor->pointedExpressionLayout() == this); // Case: Right. // Go Left. @@ -51,12 +51,12 @@ bool EmptyVisibleLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Case: Left. // Ask the parent. if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool EmptyVisibleLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool EmptyVisibleLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { assert(cursor->pointedExpressionLayout() == this); // Case: Left. // Go Right. @@ -67,7 +67,7 @@ bool EmptyVisibleLayout::moveRight(ExpressionLayoutCursor * cursor) { // Case: Right. // Ask the parent. if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } diff --git a/poincare/src/layout/empty_visible_layout.h b/poincare/src/layout/empty_visible_layout.h index 4d454d97b..0bab3e9ff 100644 --- a/poincare/src/layout/empty_visible_layout.h +++ b/poincare/src/layout/empty_visible_layout.h @@ -16,8 +16,8 @@ public: ExpressionLayout * clone() const override; void addBrother(ExpressionLayoutCursor * cursor, ExpressionLayout * brother) override; void backspaceAtCursor(ExpressionLayoutCursor * cursor) override; - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; int writeTextInBuffer(char * buffer, int bufferSize) const override; bool isEmpty() const override { return true; } Color color() const { return m_color; } diff --git a/poincare/src/layout/expression_layout.cpp b/poincare/src/layout/expression_layout.cpp index ffec0e9b8..936c7c9fd 100644 --- a/poincare/src/layout/expression_layout.cpp +++ b/poincare/src/layout/expression_layout.cpp @@ -260,26 +260,26 @@ char ExpressionLayout::XNTChar() const { return m_parent->XNTChar(); } -bool ExpressionLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool ExpressionLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { if (m_parent) { - return m_parent->moveUp(cursor, this, previousLayout); + return m_parent->moveUp(cursor, shouldRecomputeLayout, this, previousLayout); } return false; } -bool ExpressionLayout::moveUpInside(ExpressionLayoutCursor * cursor) { - return moveInside(VerticalDirection::Up, cursor); +bool ExpressionLayout::moveUpInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { + return moveInside(VerticalDirection::Up, cursor, shouldRecomputeLayout); } -bool ExpressionLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool ExpressionLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { if (m_parent) { - return m_parent->moveDown(cursor, this, previousLayout); + return m_parent->moveDown(cursor, shouldRecomputeLayout, this, previousLayout); } return false; } -bool ExpressionLayout::moveDownInside(ExpressionLayoutCursor * cursor) { - return moveInside(VerticalDirection::Down, cursor); +bool ExpressionLayout::moveDownInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { + return moveInside(VerticalDirection::Down, cursor, shouldRecomputeLayout); } bool ExpressionLayout::canBeOmittedMultiplicationLeftFactor() const { @@ -310,7 +310,7 @@ void ExpressionLayout::detachChildAtIndex(int i) { m_baselined = false; } -bool ExpressionLayout::moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor) { +bool ExpressionLayout::moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { ExpressionLayout * chilResult = nullptr; ExpressionLayout ** childResultPtr = &chilResult; ExpressionLayoutCursor::Position resultPosition = ExpressionLayoutCursor::Position::Left; @@ -318,7 +318,7 @@ bool ExpressionLayout::moveInside(VerticalDirection direction, ExpressionLayoutC // than this initial value of score. int resultScore = Ion::Display::Width*Ion::Display::Width + Ion::Display::Height*Ion::Display::Height; - moveCursorInsideAtDirection(direction, cursor, childResultPtr, &resultPosition, &resultScore); + moveCursorInsideAtDirection(direction, cursor, shouldRecomputeLayout, childResultPtr, &resultPosition, &resultScore); // If there is a valid result if (*childResultPtr == nullptr) { @@ -332,6 +332,7 @@ bool ExpressionLayout::moveInside(VerticalDirection direction, ExpressionLayoutC void ExpressionLayout::moveCursorInsideAtDirection ( VerticalDirection direction, ExpressionLayoutCursor * cursor, + bool * shouldRecomputeLayout, ExpressionLayout ** childResult, void * resultPosition, int * resultScore) @@ -361,7 +362,7 @@ void ExpressionLayout::moveCursorInsideAtDirection ( if (layoutIsUnderOrAbove || layoutContains) { int childIndex = 0; while (child(childIndex++)) { - editableChild(childIndex-1)->moveCursorInsideAtDirection(direction, cursor, childResult, castedResultPosition, resultScore); + editableChild(childIndex-1)->moveCursorInsideAtDirection(direction, cursor, shouldRecomputeLayout, childResult, castedResultPosition, resultScore); } } } diff --git a/poincare/src/layout/fraction_layout.cpp b/poincare/src/layout/fraction_layout.cpp index 4b112cfb7..82e6956ff 100644 --- a/poincare/src/layout/fraction_layout.cpp +++ b/poincare/src/layout/fraction_layout.cpp @@ -72,7 +72,7 @@ void FractionLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { ExpressionLayout::backspaceAtCursor(cursor); } -bool FractionLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool FractionLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left of the numerator or the denominator. // Go Left of the fraction. if (((numeratorLayout() && cursor->pointedExpressionLayout() == numeratorLayout()) @@ -94,12 +94,12 @@ bool FractionLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Ask the parent. assert(cursor->position() == ExpressionLayoutCursor::Position::Left); if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool FractionLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool FractionLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right of the numerator or the denominator. // Go Right of the fraction. if (((numeratorLayout() && cursor->pointedExpressionLayout() == numeratorLayout()) @@ -121,37 +121,37 @@ bool FractionLayout::moveRight(ExpressionLayoutCursor * cursor) { // Ask the parent. assert(cursor->position() == ExpressionLayoutCursor::Position::Right); if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } -bool FractionLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool FractionLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is inside denominator, move it to the numerator. if (denominatorLayout() && previousLayout == denominatorLayout()) { assert(numeratorLayout() != nullptr); - return numeratorLayout()->moveUpInside(cursor); + return numeratorLayout()->moveUpInside(cursor, shouldRecomputeLayout); } // If the cursor is Left or Right, move it to the numerator. if (cursor->pointedExpressionLayout() == this){ assert(numeratorLayout() != nullptr); - return numeratorLayout()->moveUpInside(cursor); + return numeratorLayout()->moveUpInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } -bool FractionLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool FractionLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is inside numerator, move it to the denominator. if (numeratorLayout() && previousLayout == numeratorLayout()) { assert(denominatorLayout() != nullptr); - return denominatorLayout()->moveDownInside(cursor); + return denominatorLayout()->moveDownInside(cursor, shouldRecomputeLayout); } // If the cursor is Left or Right, move it to the denominator. if (cursor->pointedExpressionLayout() == this){ assert(denominatorLayout() != nullptr); - return denominatorLayout()->moveDownInside(cursor); + return denominatorLayout()->moveDownInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveDown(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } int FractionLayout::writeTextInBuffer(char * buffer, int bufferSize) const { diff --git a/poincare/src/layout/fraction_layout.h b/poincare/src/layout/fraction_layout.h index 7c551df14..2eb341453 100644 --- a/poincare/src/layout/fraction_layout.h +++ b/poincare/src/layout/fraction_layout.h @@ -11,10 +11,10 @@ public: using StaticLayoutHierarchy::StaticLayoutHierarchy; ExpressionLayout * clone() const override; void backspaceAtCursor(ExpressionLayoutCursor * cursor) override; - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; - bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; - bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; int writeTextInBuffer(char * buffer, int bufferSize) const override; protected: void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override; diff --git a/poincare/src/layout/grid_layout.cpp b/poincare/src/layout/grid_layout.cpp index e7af88579..b5d9f9934 100644 --- a/poincare/src/layout/grid_layout.cpp +++ b/poincare/src/layout/grid_layout.cpp @@ -21,7 +21,7 @@ ExpressionLayout * GridLayout::clone() const { return layout; } -bool GridLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool GridLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right. // Go to the last entry. if (cursor->pointedExpressionLayout() == this @@ -52,12 +52,12 @@ bool GridLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Case: Left. // Ask the parent. if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool GridLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool GridLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left. // Go to the first entry. if (cursor->pointedExpressionLayout() == this @@ -89,29 +89,29 @@ bool GridLayout::moveRight(ExpressionLayoutCursor * cursor) { // Case: Right. // Ask the parent. if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } -bool GridLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool GridLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is child that is not on the top row, move it inside the upper // neighbourg. int childIndex = indexOfChild(previousLayout); if (childIndex >- 1 && !childIsTopOfGrid(childIndex)) { - return editableChild(childIndex - m_numberOfColumns)->moveUpInside(cursor); + return editableChild(childIndex - m_numberOfColumns)->moveUpInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } -bool GridLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool GridLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is child that is not on the bottom row, move it inside the // lower neighbourg. int childIndex = indexOfChild(previousLayout); if (childIndex >- 1 && !childIsBottomOfGrid(childIndex)) { - return editableChild(childIndex + m_numberOfColumns)->moveDownInside(cursor); + return editableChild(childIndex + m_numberOfColumns)->moveDownInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveDown(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } void GridLayout::removeChildAtIndex(int index, bool deleteAfterRemoval) { diff --git a/poincare/src/layout/grid_layout.h b/poincare/src/layout/grid_layout.h index d7e2915f6..ad80b8f49 100644 --- a/poincare/src/layout/grid_layout.h +++ b/poincare/src/layout/grid_layout.h @@ -13,10 +13,10 @@ public: ExpressionLayout * clone() const override; /* Navigation */ - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; - bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; - bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; /* Dynamic layout */ void removeChildAtIndex(int index, bool deleteAfterRemoval) override; diff --git a/poincare/src/layout/horizontal_layout.cpp b/poincare/src/layout/horizontal_layout.cpp index e0e27198d..baf038e23 100644 --- a/poincare/src/layout/horizontal_layout.cpp +++ b/poincare/src/layout/horizontal_layout.cpp @@ -177,13 +177,13 @@ void HorizontalLayout::addOrMergeChildAtIndex(ExpressionLayout * eL, int index, addChildAtIndex(eL, newIndex); } -bool HorizontalLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool HorizontalLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left. // Ask the parent. if (cursor->pointedExpressionLayout() == this) { if (cursor->position() == ExpressionLayoutCursor::Position::Left) { if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } @@ -194,14 +194,14 @@ bool HorizontalLayout::moveLeft(ExpressionLayoutCursor * cursor) { if (numberOfChildren() < 1) { cursor->setPosition(ExpressionLayoutCursor::Position::Left); if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } ExpressionLayout * lastChild = editableChild(numberOfChildren()-1); assert(lastChild != nullptr); cursor->setPointedExpressionLayout(lastChild); - return lastChild->moveLeft(cursor); + return lastChild->moveLeft(cursor, shouldRecomputeLayout); } // Case: The cursor is Left of a child. @@ -213,7 +213,7 @@ bool HorizontalLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Ask the parent. if (m_parent) { cursor->setPointedExpressionLayout(this); - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } @@ -221,16 +221,16 @@ bool HorizontalLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Go to its left brother and move Left. cursor->setPointedExpressionLayout(editableChild(childIndex-1)); cursor->setPosition(ExpressionLayoutCursor::Position::Right); - return editableChild(childIndex-1)->moveLeft(cursor); + return editableChild(childIndex-1)->moveLeft(cursor, shouldRecomputeLayout); } -bool HorizontalLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool HorizontalLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right. // Ask the parent. if (cursor->pointedExpressionLayout() == this) { if (cursor->position() == ExpressionLayoutCursor::Position::Right) { if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } @@ -241,14 +241,14 @@ bool HorizontalLayout::moveRight(ExpressionLayoutCursor * cursor) { if (numberOfChildren() < 1) { cursor->setPosition(ExpressionLayoutCursor::Position::Right); if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } ExpressionLayout * firstChild = editableChild(0); assert(firstChild != nullptr); cursor->setPointedExpressionLayout(firstChild); - return firstChild->moveRight(cursor); + return firstChild->moveRight(cursor, shouldRecomputeLayout); } // Case: The cursor is Right of a child. @@ -260,7 +260,7 @@ bool HorizontalLayout::moveRight(ExpressionLayoutCursor * cursor) { // Ask the parent. if (m_parent) { cursor->setPointedExpressionLayout(this); - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } @@ -268,15 +268,15 @@ bool HorizontalLayout::moveRight(ExpressionLayoutCursor * cursor) { // Go to its right brother and move Right. cursor->setPointedExpressionLayout(editableChild(childIndex+1)); cursor->setPosition(ExpressionLayoutCursor::Position::Left); - return editableChild(childIndex+1)->moveRight(cursor); + return editableChild(childIndex+1)->moveRight(cursor, shouldRecomputeLayout); } -bool HorizontalLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { - return moveVertically(ExpressionLayout::VerticalDirection::Up, cursor, previousLayout, previousPreviousLayout); +bool HorizontalLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { + return moveVertically(ExpressionLayout::VerticalDirection::Up, cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } -bool HorizontalLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { - return moveVertically(ExpressionLayout::VerticalDirection::Down, cursor, previousLayout, previousPreviousLayout); +bool HorizontalLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { + return moveVertically(ExpressionLayout::VerticalDirection::Down, cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } void HorizontalLayout::removeChildAtIndex(int index, bool deleteAfterRemoval) { @@ -341,14 +341,14 @@ KDPoint HorizontalLayout::positionOfChild(ExpressionLayout * child) { return KDPoint(x, y); } -bool HorizontalLayout::moveVertically(ExpressionLayout::VerticalDirection direction, ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool HorizontalLayout::moveVertically(ExpressionLayout::VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // Prevent looping fom child to parent if (previousPreviousLayout == this) { if (direction == ExpressionLayout::VerticalDirection::Up) { - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } assert(direction == ExpressionLayout::VerticalDirection::Down); - return ExpressionLayout::moveDown(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } // If the cursor Left or Right of a child, try moving it up from its brother. int previousLayoutIndex = indexOfChild(previousLayout); @@ -368,10 +368,10 @@ bool HorizontalLayout::moveVertically(ExpressionLayout::VerticalDirection direct ExpressionLayoutCursor::Position previousPosition = cursor->position(); cursor->setPointedExpressionLayout(brother); cursor->setPosition(newPosition); - if (direction == ExpressionLayout::VerticalDirection::Up && brother->moveUp(cursor, this, previousLayout)) { + if (direction == ExpressionLayout::VerticalDirection::Up && brother->moveUp(cursor, shouldRecomputeLayout, this, previousLayout)) { return true; } - if (direction == ExpressionLayout::VerticalDirection::Down && brother->moveDown(cursor, this, previousLayout)) { + if (direction == ExpressionLayout::VerticalDirection::Down && brother->moveDown(cursor, shouldRecomputeLayout, this, previousLayout)) { return true; } cursor->setPointedExpressionLayout(previousPointedLayout); @@ -379,10 +379,10 @@ bool HorizontalLayout::moveVertically(ExpressionLayout::VerticalDirection direct } } if (direction == ExpressionLayout::VerticalDirection::Up) { - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } assert(direction == ExpressionLayout::VerticalDirection::Down); - return ExpressionLayout::moveDown(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } } diff --git a/poincare/src/layout/horizontal_layout.h b/poincare/src/layout/horizontal_layout.h index 8516fa977..f6185545f 100644 --- a/poincare/src/layout/horizontal_layout.h +++ b/poincare/src/layout/horizontal_layout.h @@ -22,10 +22,10 @@ public: void addOrMergeChildAtIndex(ExpressionLayout * eL, int index, bool removeEmptyChildren); /* Navigation */ - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; - bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; - bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; /* Dynamic layout */ void removeChildAtIndex(int index, bool deleteAfterRemoval) override; @@ -45,7 +45,7 @@ protected: void computeBaseline() override; KDPoint positionOfChild(ExpressionLayout * child) override; private: - bool moveVertically(ExpressionLayout::VerticalDirection direction, ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout); + bool moveVertically(ExpressionLayout::VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout); void privateReplaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor); }; diff --git a/poincare/src/layout/integral_layout.cpp b/poincare/src/layout/integral_layout.cpp index 505b14cbc..48941a195 100644 --- a/poincare/src/layout/integral_layout.cpp +++ b/poincare/src/layout/integral_layout.cpp @@ -46,7 +46,7 @@ void IntegralLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { ExpressionLayout::backspaceAtCursor(cursor); } -bool IntegralLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool IntegralLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left the upper or lower bound. // Go Left of the integral. if (((upperBoundLayout() @@ -81,12 +81,12 @@ bool IntegralLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Case: Left of the brackets. // Ask the parent. if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool IntegralLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool IntegralLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right the upper or lower bound. // Go Left of the integrand. if (((upperBoundLayout() @@ -121,16 +121,16 @@ bool IntegralLayout::moveRight(ExpressionLayoutCursor * cursor) { // Case: Right. // Ask the parent. if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } -bool IntegralLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool IntegralLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is inside the lower bound, move it to the upper bound. if (lowerBoundLayout() && previousLayout == lowerBoundLayout()) { assert(upperBoundLayout() != nullptr); - return upperBoundLayout()->moveUpInside(cursor); + return upperBoundLayout()->moveUpInside(cursor, shouldRecomputeLayout); } // If the cursor is Left of the integrand, move it to the upper bound. if (integrandLayout() @@ -138,16 +138,16 @@ bool IntegralLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * && cursor->positionIsEquivalentTo(integrandLayout(), ExpressionLayoutCursor::Position::Left)) { assert(upperBoundLayout() != nullptr); - return upperBoundLayout()->moveUpInside(cursor); + return upperBoundLayout()->moveUpInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } -bool IntegralLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool IntegralLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is inside the upper bound, move it to the lower bound. if (upperBoundLayout() && previousLayout == upperBoundLayout()) { assert(lowerBoundLayout() != nullptr); - return lowerBoundLayout()->moveDownInside(cursor); + return lowerBoundLayout()->moveDownInside(cursor, shouldRecomputeLayout); } // If the cursor is Left of the integrand, move it to the lower bound. if (integrandLayout() @@ -155,9 +155,9 @@ bool IntegralLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout && cursor->positionIsEquivalentTo(integrandLayout(), ExpressionLayoutCursor::Position::Left)) { assert(lowerBoundLayout() != nullptr); - return lowerBoundLayout()->moveDownInside(cursor); + return lowerBoundLayout()->moveDownInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveDown(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } int IntegralLayout::writeTextInBuffer(char * buffer, int bufferSize) const { diff --git a/poincare/src/layout/integral_layout.h b/poincare/src/layout/integral_layout.h index 35e9769df..56cb14999 100644 --- a/poincare/src/layout/integral_layout.h +++ b/poincare/src/layout/integral_layout.h @@ -17,10 +17,10 @@ public: void backspaceAtCursor(ExpressionLayoutCursor * cursor) override; /* Tree navigation */ - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; - bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; - bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; /* Expression Engine */ int writeTextInBuffer(char * buffer, int bufferSize) const override; diff --git a/poincare/src/layout/matrix_layout.cpp b/poincare/src/layout/matrix_layout.cpp index 82467984e..753b3e7b4 100644 --- a/poincare/src/layout/matrix_layout.cpp +++ b/poincare/src/layout/matrix_layout.cpp @@ -17,7 +17,7 @@ ExpressionLayout * MatrixLayout::clone() const { return layout; } -bool MatrixLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool MatrixLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { int childIndex = indexOfChild(cursor->pointedExpressionLayout()); if (childIndex >- 1 && cursor->position() == ExpressionLayoutCursor::Position::Left @@ -27,6 +27,7 @@ bool MatrixLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Remove the grey squares of the grid, then go left of the grid. assert(hasGreySquares()); removeGreySquares(); + *shouldRecomputeLayout = true; cursor->setPointedExpressionLayout(this); cursor->setPosition(ExpressionLayoutCursor::Position::Left); return true; @@ -39,15 +40,16 @@ bool MatrixLayout::moveLeft(ExpressionLayoutCursor * cursor) { { assert(!hasGreySquares()); addGreySquares(); + *shouldRecomputeLayout = true; ExpressionLayout * lastChild = editableChild((m_numberOfColumns-1)*(m_numberOfRows-1)); assert(lastChild != nullptr); cursor->setPointedExpressionLayout(lastChild); return true; } - return GridLayout::moveLeft(cursor); + return GridLayout::moveLeft(cursor, shouldRecomputeLayout); } -bool MatrixLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool MatrixLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left. // Add the grey squares to the matrix,, then go to the first entry. if (cursor->pointedExpressionLayout() == this @@ -55,6 +57,7 @@ bool MatrixLayout::moveRight(ExpressionLayoutCursor * cursor) { { assert(!hasGreySquares()); addGreySquares(); + *shouldRecomputeLayout = true; assert(m_numberOfColumns*m_numberOfRows >= 1); ExpressionLayout * firstChild = editableChild(0); assert(firstChild != nullptr); @@ -73,25 +76,28 @@ bool MatrixLayout::moveRight(ExpressionLayoutCursor * cursor) { cursor->setPosition(ExpressionLayoutCursor::Position::Right); assert(hasGreySquares()); removeGreySquares(); + *shouldRecomputeLayout = true; return true; } - return GridLayout::moveRight(cursor); + return GridLayout::moveRight(cursor, shouldRecomputeLayout); } -bool MatrixLayout::moveUpInside(ExpressionLayoutCursor * cursor) { - bool result = GridLayout::moveUpInside(cursor); +bool MatrixLayout::moveUpInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { + bool result = GridLayout::moveUpInside(cursor, shouldRecomputeLayout); if (result) { assert(!hasGreySquares()); addGreySquares(); + *shouldRecomputeLayout = true; } return result; } -bool MatrixLayout::moveDownInside(ExpressionLayoutCursor * cursor) { - bool result = GridLayout::moveDownInside(cursor); +bool MatrixLayout::moveDownInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { + bool result = GridLayout::moveDownInside(cursor, shouldRecomputeLayout); if (result) { assert(!hasGreySquares()); addGreySquares(); + *shouldRecomputeLayout = true; } return result; } diff --git a/poincare/src/layout/matrix_layout.h b/poincare/src/layout/matrix_layout.h index 8208d11b3..2a4633b6d 100644 --- a/poincare/src/layout/matrix_layout.h +++ b/poincare/src/layout/matrix_layout.h @@ -11,10 +11,10 @@ public: ExpressionLayout * clone() const override; /* Navigation */ - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; - bool moveUpInside(ExpressionLayoutCursor * cursor) override; - bool moveDownInside(ExpressionLayoutCursor * cursor) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveUpInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveDownInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; /* Dynamic layout */ void replaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild) override; diff --git a/poincare/src/layout/nth_root_layout.cpp b/poincare/src/layout/nth_root_layout.cpp index 8c14bfe19..291171463 100644 --- a/poincare/src/layout/nth_root_layout.cpp +++ b/poincare/src/layout/nth_root_layout.cpp @@ -45,7 +45,7 @@ void NthRootLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { ExpressionLayout::backspaceAtCursor(cursor); } -bool NthRootLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool NthRootLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left of the radicand. // Go the index if there is one, else go Left of the root. if (radicandLayout() @@ -81,12 +81,12 @@ bool NthRootLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Case: Left. // Ask the parent. if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool NthRootLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool NthRootLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right of the radicand. // Go the Right of the root. if (radicandLayout() @@ -123,12 +123,12 @@ bool NthRootLayout::moveRight(ExpressionLayoutCursor * cursor) { // Case: Right. // Ask the parent. if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } -bool NthRootLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool NthRootLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is Left of the radicand, move it to the index. if (indexLayout() && radicandLayout() @@ -148,10 +148,10 @@ bool NthRootLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * p cursor->setPosition(ExpressionLayoutCursor::Position::Left); return true; } - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } -bool NthRootLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool NthRootLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { if (indexLayout() && previousLayout == indexLayout()) { // If the cursor is Right of the index, move it to the radicand. if (cursor->positionIsEquivalentTo(indexLayout(), ExpressionLayoutCursor::Position::Right)) { @@ -167,7 +167,7 @@ bool NthRootLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * return true; } } - return ExpressionLayout::moveDown(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } static_assert('\x90' == Ion::Charset::Root, "Unicode error"); diff --git a/poincare/src/layout/nth_root_layout.h b/poincare/src/layout/nth_root_layout.h index 86a840b55..e97d05595 100644 --- a/poincare/src/layout/nth_root_layout.h +++ b/poincare/src/layout/nth_root_layout.h @@ -17,10 +17,10 @@ public: void backspaceAtCursor(ExpressionLayoutCursor * cursor) override; /* Tree navigation */ - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; - bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; - bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; /* Expression Engine */ int writeTextInBuffer(char * buffer, int bufferSize) const override; diff --git a/poincare/src/layout/parenthesis_left_right_layout.cpp b/poincare/src/layout/parenthesis_left_right_layout.cpp index 060596fac..b7d8f819e 100644 --- a/poincare/src/layout/parenthesis_left_right_layout.cpp +++ b/poincare/src/layout/parenthesis_left_right_layout.cpp @@ -18,7 +18,7 @@ void ParenthesisLeftRightLayout::invalidAllSizesPositionsAndBaselines() { ExpressionLayout::invalidAllSizesPositionsAndBaselines(); } -bool ParenthesisLeftRightLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool ParenthesisLeftRightLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { assert(cursor->pointedExpressionLayout() == this); // Case: Right. // Go Left. @@ -30,12 +30,12 @@ bool ParenthesisLeftRightLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Case: Left. // Ask the parent. if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool ParenthesisLeftRightLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool ParenthesisLeftRightLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { assert(cursor->pointedExpressionLayout() == this); // Case: Left. // Go Right. @@ -47,7 +47,7 @@ bool ParenthesisLeftRightLayout::moveRight(ExpressionLayoutCursor * cursor) { // Case: Right. // Ask the parent. if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } diff --git a/poincare/src/layout/parenthesis_left_right_layout.h b/poincare/src/layout/parenthesis_left_right_layout.h index 8596d219b..0dc125452 100644 --- a/poincare/src/layout/parenthesis_left_right_layout.h +++ b/poincare/src/layout/parenthesis_left_right_layout.h @@ -9,8 +9,8 @@ class ParenthesisLeftRightLayout : public StaticLayoutHierarchy<0> { public: ParenthesisLeftRightLayout(); void invalidAllSizesPositionsAndBaselines() override; - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; constexpr static KDCoordinate parenthesisWidth() { return k_widthMargin + k_lineThickness + k_externWidthMargin; } constexpr static KDCoordinate k_parenthesisCurveWidth = 5; constexpr static KDCoordinate k_parenthesisCurveHeight = 7; diff --git a/poincare/src/layout/sequence_layout.cpp b/poincare/src/layout/sequence_layout.cpp index b9a91e85b..94a64aa37 100644 --- a/poincare/src/layout/sequence_layout.cpp +++ b/poincare/src/layout/sequence_layout.cpp @@ -20,7 +20,7 @@ void SequenceLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { ExpressionLayout::backspaceAtCursor(cursor); } -bool SequenceLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool SequenceLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left of the bounds. // Go Left of the sequence. if (cursor->position() == ExpressionLayoutCursor::Position::Left @@ -55,12 +55,12 @@ bool SequenceLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Case: Left. // Ask the parent. if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool SequenceLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool SequenceLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right of the bounds. // Go Left of the argument. if (cursor->position() == ExpressionLayoutCursor::Position::Right @@ -96,40 +96,40 @@ bool SequenceLayout::moveRight(ExpressionLayoutCursor * cursor) { // Case: Right. // Ask the parent. if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } -bool SequenceLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool SequenceLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is inside the lower bound, move it to the upper bound. if (lowerBoundLayout() && previousLayout == lowerBoundLayout()) { assert(upperBoundLayout() != nullptr); - return upperBoundLayout()->moveUpInside(cursor); + return upperBoundLayout()->moveUpInside(cursor, shouldRecomputeLayout); } // If the cursor is Left of the argument, move it to the upper bound. if (argumentLayout() && cursor->positionIsEquivalentTo(argumentLayout(), ExpressionLayoutCursor::Position::Left)) { assert(upperBoundLayout() != nullptr); - return upperBoundLayout()->moveUpInside(cursor); + return upperBoundLayout()->moveUpInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } -bool SequenceLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool SequenceLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is inside the upper bound, move it to the lower bound. if (upperBoundLayout() && previousLayout == upperBoundLayout()) { assert(lowerBoundLayout() != nullptr); - return lowerBoundLayout()->moveDownInside(cursor); + return lowerBoundLayout()->moveDownInside(cursor, shouldRecomputeLayout); } // If the cursor is Left of the argument, move it to the lower bound. if (argumentLayout() && cursor->positionIsEquivalentTo(argumentLayout(), ExpressionLayoutCursor::Position::Left)) { assert(lowerBoundLayout() != nullptr); - return lowerBoundLayout()->moveDownInside(cursor); + return lowerBoundLayout()->moveDownInside(cursor, shouldRecomputeLayout); } - return ExpressionLayout::moveDown(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } char SequenceLayout::XNTChar() const { diff --git a/poincare/src/layout/sequence_layout.h b/poincare/src/layout/sequence_layout.h index ef92f3f68..f7c77d5b2 100644 --- a/poincare/src/layout/sequence_layout.h +++ b/poincare/src/layout/sequence_layout.h @@ -11,10 +11,10 @@ public: constexpr static KDCoordinate k_symbolHeight = 15; constexpr static KDCoordinate k_symbolWidth = 9; void backspaceAtCursor(ExpressionLayoutCursor * cursor) override; - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; - bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; - bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; char XNTChar() const override; protected: constexpr static KDCoordinate k_boundHeightMargin = 2; diff --git a/poincare/src/layout/vertical_offset_layout.cpp b/poincare/src/layout/vertical_offset_layout.cpp index 7f3fac07c..89b25fb24 100644 --- a/poincare/src/layout/vertical_offset_layout.cpp +++ b/poincare/src/layout/vertical_offset_layout.cpp @@ -57,7 +57,7 @@ void VerticalOffsetLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { ExpressionLayout::backspaceAtCursor(cursor); } -bool VerticalOffsetLayout::moveLeft(ExpressionLayoutCursor * cursor) { +bool VerticalOffsetLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Left of the indice. // Go Left. if (indiceLayout() @@ -81,12 +81,12 @@ bool VerticalOffsetLayout::moveLeft(ExpressionLayoutCursor * cursor) { // Ask the parent. assert(cursor->position() == ExpressionLayoutCursor::Position::Left); if (m_parent) { - return m_parent->moveLeft(cursor); + return m_parent->moveLeft(cursor, shouldRecomputeLayout); } return false; } -bool VerticalOffsetLayout::moveRight(ExpressionLayoutCursor * cursor) { +bool VerticalOffsetLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) { // Case: Right of the indice. // Go Right. if (indiceLayout() @@ -109,12 +109,12 @@ bool VerticalOffsetLayout::moveRight(ExpressionLayoutCursor * cursor) { // Ask the parent. assert(cursor->position() == ExpressionLayoutCursor::Position::Right); if (m_parent) { - return m_parent->moveRight(cursor); + return m_parent->moveRight(cursor, shouldRecomputeLayout); } return false; } -bool VerticalOffsetLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool VerticalOffsetLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // Case: Superscript. if (m_type == VerticalOffsetLayout::Type::Superscript) { // Case: Right. @@ -145,10 +145,10 @@ bool VerticalOffsetLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLay cursor->setPointedExpressionLayout(this); return true; } - return ExpressionLayout::moveUp(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } -bool VerticalOffsetLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { +bool VerticalOffsetLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // Case: Subscript. if (m_type == VerticalOffsetLayout::Type::Subscript) { // Case: Right. @@ -178,7 +178,7 @@ bool VerticalOffsetLayout::moveDown(ExpressionLayoutCursor * cursor, ExpressionL cursor->setPointedExpressionLayout(this); return true; } - return ExpressionLayout::moveDown(cursor, previousLayout, previousPreviousLayout); + return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, previousLayout, previousPreviousLayout); } int VerticalOffsetLayout::writeTextInBuffer(char * buffer, int bufferSize) const { diff --git a/poincare/src/layout/vertical_offset_layout.h b/poincare/src/layout/vertical_offset_layout.h index bf3242cb7..75ca9f1e3 100644 --- a/poincare/src/layout/vertical_offset_layout.h +++ b/poincare/src/layout/vertical_offset_layout.h @@ -14,10 +14,10 @@ public: VerticalOffsetLayout(ExpressionLayout * indice, Type type, bool cloneOperands); ExpressionLayout * clone() const override; void backspaceAtCursor(ExpressionLayoutCursor * cursor) override; - bool moveLeft(ExpressionLayoutCursor * cursor) override; - bool moveRight(ExpressionLayoutCursor * cursor) override; - bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; - bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout = nullptr) override; + bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; + bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) override; int writeTextInBuffer(char * buffer, int bufferSize) const override; bool mustHaveLeftBrother() const override { return true; } protected: