diff --git a/poincare/include/poincare/fraction_layout.h b/poincare/include/poincare/fraction_layout.h index 99a054aa2..8c6c4d101 100644 --- a/poincare/include/poincare/fraction_layout.h +++ b/poincare/include/poincare/fraction_layout.h @@ -22,6 +22,7 @@ public: int serialize(char * buffer, int bufferSize, Preferences::PrintFloatMode floatDisplayMode, int numberOfSignificantDigits) const override; + bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const override; bool shouldCollapseSiblingsOnLeft() const override { return true; } bool shouldCollapseSiblingsOnRight() const override { return true; } int leftCollapsingAbsorbingChildIndex() const override { return 0; } diff --git a/poincare/src/fraction_layout.cpp b/poincare/src/fraction_layout.cpp index 43dc8f7c3..ac035cf1b 100644 --- a/poincare/src/fraction_layout.cpp +++ b/poincare/src/fraction_layout.cpp @@ -161,6 +161,24 @@ LayoutNode * FractionLayoutNode::layoutToPointWhenInserting(Expression * corresp return this; } +bool FractionLayoutNode::isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const { + if (*numberOfOpenParenthesis > 0) { + return true; + } + + /* We do not want to absorb a fraction if something else is already being + * absorbed. This way, the user can write a product of fractions without + * typing the × sign. */ + Layout p = Layout(parent()); + assert(!p.isUninitialized() && p.type() == LayoutNode::Type::HorizontalLayout); + int indexInParent = p.indexOfChild(Layout(this)); + int indexOfAbsorbingSibling = indexInParent + (goingLeft ? 1 : -1); + assert(indexOfAbsorbingSibling >= 0 && indexOfAbsorbingSibling < p.numberOfChildren()); + Layout absorbingSibling = p.childAtIndex(indexOfAbsorbingSibling); + Layout absorbingChild = absorbingSibling.childAtIndex((goingLeft) ? absorbingSibling.leftCollapsingAbsorbingChildIndex() : absorbingSibling.rightCollapsingAbsorbingChildIndex()); + return absorbingChild.type() == LayoutNode::Type::HorizontalLayout && absorbingChild.isEmpty(); +} + void FractionLayoutNode::didCollapseSiblings(LayoutCursor * cursor) { if (cursor != nullptr) { cursor->setLayoutNode(denominatorLayout());