From 8a7e4e598c2440c362a5d06614e128559ccf30a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Wed, 3 Jan 2018 17:23:35 +0100 Subject: [PATCH] [expression_editor] Collapse brothers when adding a fraction. Change-Id: I4d75fae152fca4a6671abd1e444f6aaa27c168b5 --- apps/expression_editor/controller.cpp | 2 +- .../poincare/dynamic_layout_hierarchy.h | 2 + .../poincare/expression_layout_cursor.h | 2 +- poincare/src/expression_layout_cursor.cpp | 58 ++++++++++++++----- poincare/src/layout/horizontal_layout.cpp | 10 +++- 5 files changed, 56 insertions(+), 18 deletions(-) diff --git a/apps/expression_editor/controller.cpp b/apps/expression_editor/controller.cpp index 7c717f585..2df023056 100644 --- a/apps/expression_editor/controller.cpp +++ b/apps/expression_editor/controller.cpp @@ -106,7 +106,7 @@ bool Controller::handleMoveEvent(Ion::Events::Event event) { ExpressionLayout * Controller::handleAddEvent(Ion::Events::Event event) { if (event == Ion::Events::Division) { - return m_cursor.addEmptyFractionLayout(); + return m_cursor.addFractionLayoutAndCollapseBrothers(); } if (event == Ion::Events::XNT) { return m_cursor.addXNTCharLayout(); diff --git a/poincare/include/poincare/dynamic_layout_hierarchy.h b/poincare/include/poincare/dynamic_layout_hierarchy.h index 0a7fd488e..8e4cffd6a 100644 --- a/poincare/include/poincare/dynamic_layout_hierarchy.h +++ b/poincare/include/poincare/dynamic_layout_hierarchy.h @@ -10,6 +10,8 @@ class DynamicLayoutHierarchy : public ExpressionLayout { public: DynamicLayoutHierarchy(); DynamicLayoutHierarchy(const ExpressionLayout * const * operands, int numberOfOperands, bool cloneOperands = true); + DynamicLayoutHierarchy(const ExpressionLayout * operand, bool cloneOperands = true) : + DynamicLayoutHierarchy(ExpressionLayoutArray(operand).array(), 1, cloneOperands) {} DynamicLayoutHierarchy(const ExpressionLayout * operand1, const ExpressionLayout * operand2, bool cloneOperands = true) : DynamicLayoutHierarchy(ExpressionLayoutArray(operand1, operand2).array(), 2, cloneOperands) {} ~DynamicLayoutHierarchy(); diff --git a/poincare/include/poincare/expression_layout_cursor.h b/poincare/include/poincare/expression_layout_cursor.h index b92bff74e..e6c5e9f71 100644 --- a/poincare/include/poincare/expression_layout_cursor.h +++ b/poincare/include/poincare/expression_layout_cursor.h @@ -45,7 +45,7 @@ public: /* Edition */ void addLayout(ExpressionLayout * layout); ExpressionLayout * addEmptyExponentialLayout(); - ExpressionLayout * addEmptyFractionLayout(); + ExpressionLayout * addFractionLayoutAndCollapseBrothers(); ExpressionLayout * addEmptyLogarithmLayout(); ExpressionLayout * addEmptyPowerLayout(); ExpressionLayout * addEmptyRootLayout(); diff --git a/poincare/src/expression_layout_cursor.cpp b/poincare/src/expression_layout_cursor.cpp index f24cc664e..0f55d45fa 100644 --- a/poincare/src/expression_layout_cursor.cpp +++ b/poincare/src/expression_layout_cursor.cpp @@ -1,14 +1,5 @@ #include -#include -#include //TODO move from there. -#include //TODO move from there. -#include //TODO move from there. -#include //TODO move from there. -#include //TODO move from there. -#include //TODO move from there. -#include //TODO move from there. -#include //TODO move from there. -#include //TODO move from there. +#include //TODO: finer include? #include #include @@ -66,12 +57,51 @@ ExpressionLayout * ExpressionLayoutCursor::addEmptyExponentialLayout() { return child2; } -ExpressionLayout * ExpressionLayoutCursor::addEmptyFractionLayout() { - EmptyVisibleLayout * child1 = new EmptyVisibleLayout(); - EmptyVisibleLayout * child2 = new EmptyVisibleLayout(); +ExpressionLayout * ExpressionLayoutCursor::addFractionLayoutAndCollapseBrothers() { + // Add a new FractionLayout + HorizontalLayout * child1 = new HorizontalLayout(new EmptyVisibleLayout()); + HorizontalLayout * child2 = new HorizontalLayout(new EmptyVisibleLayout()); FractionLayout * newChild = new FractionLayout(child1, child2, false); pointedExpressionLayout()->addBrother(this, newChild); - return child1; + + if (!newChild->parent()->isHorizontal()) { + setPointedExpressionLayout(child2->editableChild(0)); + setPosition(Position::Left); + return child2; + } + + int fractionIndexInParent = newChild->parent()->indexOfChild(newChild); + int numberOfBrothers = newChild->parent()->numberOfChildren(); + + // Collapse the brothers on the right + int numberOfOpenParenthesis = 0; + while (fractionIndexInParent < numberOfBrothers - 1) { + ExpressionLayout * rightBrother = newChild->editableParent()->editableChild(fractionIndexInParent+1); + if (rightBrother->isCollapsable(&numberOfOpenParenthesis, false)) { + newChild->editableParent()->removeChildAtIndex(fractionIndexInParent+1, false); + child2->addOrMergeChildAtIndex(rightBrother, child2->numberOfChildren()); + numberOfBrothers--; + } else { + break; + } + } + // Collapse the brothers on the left + numberOfOpenParenthesis = 0; + while (fractionIndexInParent > 0) { + ExpressionLayout * leftBrother = newChild->editableParent()->editableChild(fractionIndexInParent-1); + if (leftBrother->isCollapsable(&numberOfOpenParenthesis, true)) { + newChild->editableParent()->removeChildAtIndex(fractionIndexInParent-1, false); + child1->addOrMergeChildAtIndex(leftBrother, 0); + fractionIndexInParent--; + } else { + break; + } + } + // Set the cursor position + setPointedExpressionLayout(child2->editableChild(0)); + setPosition(Position::Left); + + return child2; } ExpressionLayout * ExpressionLayoutCursor::addEmptyLogarithmLayout() { diff --git a/poincare/src/layout/horizontal_layout.cpp b/poincare/src/layout/horizontal_layout.cpp index 38d125e6c..6a92ff30d 100644 --- a/poincare/src/layout/horizontal_layout.cpp +++ b/poincare/src/layout/horizontal_layout.cpp @@ -52,11 +52,17 @@ void HorizontalLayout::replaceChild(const ExpressionLayout * oldChild, Expressio } void HorizontalLayout::addOrMergeChildAtIndex(ExpressionLayout * eL, int index) { + int newIndex = index; + if (numberOfChildren() > 0 && child(0)->isEmpty()) { + removeChildAtIndex(0, true); + newIndex = index == 0 ? 0 : index - 1; + } if (eL->isHorizontal()) { - mergeChildrenAtIndex(eL, index); + mergeChildrenAtIndex(eL, newIndex); return; } - addChildAtIndex(eL, index); + addChildAtIndex(eL, newIndex); + } bool HorizontalLayout::moveLeft(ExpressionLayoutCursor * cursor) {