diff --git a/apps/expression_editor/controller.cpp b/apps/expression_editor/controller.cpp index 052815e49..8e9c77078 100644 --- a/apps/expression_editor/controller.cpp +++ b/apps/expression_editor/controller.cpp @@ -118,7 +118,7 @@ ExpressionLayout * Controller::handleAddEvent(Ion::Events::Event event) { return m_cursor.addEmptyPowerLayout(); } if (event == Ion::Events::Sqrt) { - return m_cursor.addEmptyRootLayout(); + return m_cursor.addEmptySquareRootLayout(); } if (event == Ion::Events::Square) { return m_cursor.addEmptySquarePowerLayout(); diff --git a/poincare/include/poincare/expression_layout_cursor.h b/poincare/include/poincare/expression_layout_cursor.h index 76b335f1c..779cd9318 100644 --- a/poincare/include/poincare/expression_layout_cursor.h +++ b/poincare/include/poincare/expression_layout_cursor.h @@ -44,7 +44,7 @@ public: ExpressionLayout * addFractionLayoutAndCollapseBrothers(); ExpressionLayout * addEmptyLogarithmLayout(); ExpressionLayout * addEmptyPowerLayout(); - ExpressionLayout * addEmptyRootLayout(); + ExpressionLayout * addEmptySquareRootLayout(); ExpressionLayout * addEmptySquarePowerLayout(); ExpressionLayout * addXNTCharLayout(); ExpressionLayout * insertText(const char * text); diff --git a/poincare/src/expression_layout_cursor.cpp b/poincare/src/expression_layout_cursor.cpp index c22d3430b..1070b4167 100644 --- a/poincare/src/expression_layout_cursor.cpp +++ b/poincare/src/expression_layout_cursor.cpp @@ -127,10 +127,9 @@ ExpressionLayout * ExpressionLayoutCursor::addEmptyPowerLayout() { return child1; } -ExpressionLayout * ExpressionLayoutCursor::addEmptyRootLayout() { +ExpressionLayout * ExpressionLayoutCursor::addEmptySquareRootLayout() { EmptyVisibleLayout * child1 = new EmptyVisibleLayout(); - EmptyVisibleLayout * child2 = new EmptyVisibleLayout(); - NthRootLayout * newChild = new NthRootLayout(child1, child2, false); + NthRootLayout * newChild = new NthRootLayout(child1, false); m_pointedExpressionLayout->addBrother(this, newChild); setPointedExpressionLayout(child1); setPosition(ExpressionLayoutCursor::Position::Right); diff --git a/poincare/src/layout/nth_root_layout.cpp b/poincare/src/layout/nth_root_layout.cpp index 8d8ab0aa1..8831869c7 100644 --- a/poincare/src/layout/nth_root_layout.cpp +++ b/poincare/src/layout/nth_root_layout.cpp @@ -17,14 +17,18 @@ const uint8_t radixPixel[NthRootLayout::k_leftRadixHeight][NthRootLayout::k_left }; ExpressionLayout * NthRootLayout::clone() const { - NthRootLayout * layout = new NthRootLayout(const_cast(this)->radicandLayout(), const_cast(this)->indexLayout(), true); - return layout; + if (numberOfChildren() == 1) { + return new NthRootLayout(const_cast(this)->radicandLayout(), true); + } + assert(numberOfChildren() == 2); + return new NthRootLayout(const_cast(this)->radicandLayout(), const_cast(this)->indexLayout(), true); } void NthRootLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { // Case: Left the index. // Move Left. - if (cursor->position() == ExpressionLayoutCursor::Position::Left + if (indexLayout() + && cursor->position() == ExpressionLayoutCursor::Position::Left && cursor->pointedExpressionLayout() == indexLayout()) { cursor->setPointedExpressionLayout(this); @@ -64,7 +68,7 @@ void NthRootLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { } // Case: Left. // Ask the parent. - assert(cursor->position() ==ExpressionLayoutCursor::Position::Left); + assert(cursor->position() == ExpressionLayoutCursor::Position::Left); if (m_parent) { return m_parent->backspaceAtCursor(cursor); } @@ -155,20 +159,20 @@ bool NthRootLayout::moveRight(ExpressionLayoutCursor * cursor) { bool NthRootLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { // If the cursor is Left of the radicand, move it to the index. - if (radicandLayout() + if (indexLayout() + && radicandLayout() && previousLayout == radicandLayout() && cursor->positionIsEquivalentTo(radicandLayout(), ExpressionLayoutCursor::Position::Left)) { - assert(indexLayout() != nullptr); cursor->setPointedExpressionLayout(indexLayout()); cursor->setPosition(ExpressionLayoutCursor::Position::Right); return true; } // If the cursor is Left, move it to the index. - if (cursor->pointedExpressionLayout() == this + if (indexLayout() + && cursor->pointedExpressionLayout() == this && cursor->position() == ExpressionLayoutCursor::Position::Left) { - assert(indexLayout() != nullptr); cursor->setPointedExpressionLayout(indexLayout()); cursor->setPosition(ExpressionLayoutCursor::Position::Left); return true; @@ -260,12 +264,12 @@ KDPoint NthRootLayout::positionOfChild(ExpressionLayout * child) { KDCoordinate x = 0; KDCoordinate y = 0; KDSize indexSize = indexLayout() != nullptr ? indexLayout()->size() : KDSize(k_leftRadixWidth,0); - if (child == indexLayout()) { - x = 0; - y = baseline() - indexSize.height() - k_indexHeight; - } else if (child == radicandLayout()) { + if (child == radicandLayout()) { x = indexSize.width() + 2*k_widthMargin + k_radixLineThickness; y = baseline() - radicandLayout()->baseline(); + } else if (indexLayout() && child == indexLayout()) { + x = 0; + y = baseline() - indexSize.height() - k_indexHeight; } else { assert(false); } @@ -277,7 +281,10 @@ ExpressionLayout * NthRootLayout::radicandLayout() { } ExpressionLayout * NthRootLayout::indexLayout() { - return editableChild(1); + if (numberOfChildren() > 1) { + return editableChild(1); + } + return nullptr; } } diff --git a/poincare/src/layout/nth_root_layout.h b/poincare/src/layout/nth_root_layout.h index c04f5c7f2..fb2a54048 100644 --- a/poincare/src/layout/nth_root_layout.h +++ b/poincare/src/layout/nth_root_layout.h @@ -1,16 +1,16 @@ #ifndef POINCARE_NTH_ROOT_LAYOUT_H #define POINCARE_NTH_ROOT_LAYOUT_H -#include +#include #include namespace Poincare { -class NthRootLayout : public StaticLayoutHierarchy<2> { +class NthRootLayout : public BoundedStaticLayoutHierarchy<2> { public: constexpr static KDCoordinate k_leftRadixHeight = 8; constexpr static KDCoordinate k_leftRadixWidth = 5; - using StaticLayoutHierarchy::StaticLayoutHierarchy; + using BoundedStaticLayoutHierarchy::BoundedStaticLayoutHierarchy; ExpressionLayout * clone() const override; /* Dynamic Layout*/ diff --git a/poincare/src/layout/static_layout_hierarchy.cpp b/poincare/src/layout/static_layout_hierarchy.cpp index 76314772e..224902945 100644 --- a/poincare/src/layout/static_layout_hierarchy.cpp +++ b/poincare/src/layout/static_layout_hierarchy.cpp @@ -52,8 +52,7 @@ void StaticLayoutHierarchy::build(const ExpressionLayout * const * operands, assert(operands != nullptr); assert(numberOfOperands <= T); for (int i=0; i < numberOfOperands; i++) { - assert(operands[i] != nullptr); - if (cloneOperands) { + if (cloneOperands && operands[i] != nullptr) { m_children[i] = operands[i]->clone(); } else { m_children[i] = operands[i];