From f95bb46cc38e0dd2ff0010953474893dac81c504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Thu, 11 Jan 2018 11:08:58 +0100 Subject: [PATCH] [poincare] Cleaned ExpressionLayout class. Change-Id: I03a49e1a2b199a70608792f0358ddde5a86118d6 --- poincare/include/poincare/expression_layout.h | 67 +++++++++----- poincare/src/layout/expression_layout.cpp | 91 +++++++++---------- poincare/src/layout/horizontal_layout.cpp | 6 +- poincare/src/layout/matrix_layout.cpp | 4 +- 4 files changed, 92 insertions(+), 76 deletions(-) diff --git a/poincare/include/poincare/expression_layout.h b/poincare/include/poincare/expression_layout.h index 715ad8fbe..473827679 100644 --- a/poincare/include/poincare/expression_layout.h +++ b/poincare/include/poincare/expression_layout.h @@ -32,38 +32,60 @@ public: virtual void invalidAllSizesPositionsAndBaselines(); /* Hierarchy */ + + // Children virtual const ExpressionLayout * const * children() const = 0; const ExpressionLayout * child(int i) const; ExpressionLayout * editableChild(int i) { return const_cast(child(i)); } virtual int numberOfChildren() const = 0; - int indexOfChild(ExpressionLayout * child) const; + int indexOfChild(const ExpressionLayout * child) const; - void setParent(ExpressionLayout * parent); + // Parent + void setParent(ExpressionLayout * parent) { m_parent = parent; } const ExpressionLayout * parent() const { return m_parent; } ExpressionLayout * editableParent() { return m_parent; } bool hasAncestor(const ExpressionLayout * e) const; /* Dynamic Layout */ - bool insertLayoutAtCursor(ExpressionLayout * newChild, ExpressionLayoutCursor * cursor); + + // Add + virtual bool addChildAtIndex(ExpressionLayout * child, int index) { return false; } virtual void addBrother(ExpressionLayoutCursor * cursor, ExpressionLayout * brother); + + // Replace virtual ExpressionLayout * replaceWith(ExpressionLayout * newChild, bool deleteAfterReplace = true); - ExpressionLayout * replaceWithJuxtapositionOf(ExpressionLayout * leftChild, ExpressionLayout * rightChild, bool deleteAfterReplace); ExpressionLayout * replaceWithAndMoveCursor(ExpressionLayout * newChild, bool deleteAfterReplace, ExpressionLayoutCursor * cursor); virtual void replaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild = true); - virtual void replaceChildAndMoveCursor(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor); - void detachChild(const ExpressionLayout * e); // Removes a child WITHOUT deleting it - void detachChildren(); //Removes all children WITHOUT deleting them - virtual bool addChildAtIndex(ExpressionLayout * child, int index) { return false; } + virtual void replaceChildAndMoveCursor( + const ExpressionLayout * oldChild, + ExpressionLayout * newChild, + bool deleteOldChild, + ExpressionLayoutCursor * cursor); + + // Detach + void detachChild(const ExpressionLayout * e); // Detach a child WITHOUT deleting it + void detachChildren(); // Detach all children WITHOUT deleting them + + // Remove virtual void removeChildAtIndex(int index, bool deleteAfterRemoval); virtual void removePointedChildAtIndexAndMoveCursor(int index, bool deleteAfterRemoval, ExpressionLayoutCursor * cursor); + + // User input + bool insertLayoutAtCursor(ExpressionLayout * newChild, ExpressionLayoutCursor * cursor); virtual void backspaceAtCursor(ExpressionLayoutCursor * cursor); /* Tree navigation */ virtual bool moveLeft(ExpressionLayoutCursor * cursor) { return false; } //TODO should be virtual pure? virtual bool moveRight(ExpressionLayoutCursor * cursor) { return false; } //TODO should be virtual pure? - virtual bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout = nullptr, ExpressionLayout * previousPreviousLayout = nullptr); + virtual bool moveUp( + ExpressionLayoutCursor * cursor, + ExpressionLayout * previousLayout = nullptr, + ExpressionLayout * previousPreviousLayout = nullptr); + virtual bool moveDown( + ExpressionLayoutCursor * cursor, + ExpressionLayout * previousLayout = nullptr, + ExpressionLayout * previousPreviousLayout = nullptr); bool moveUpInside(ExpressionLayoutCursor * cursor); - virtual bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout = nullptr, ExpressionLayout * previousPreviousLayout = nullptr); bool moveDownInside(ExpressionLayoutCursor * cursor); /* Expression Engine */ @@ -71,7 +93,8 @@ public: /* Other */ virtual bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const { return true; } - // isCollapsable is used when adding a brother fraction: should the layout be inserted in the numerator (or denominator)? + /* isCollapsable is used when adding a brother fraction: should the layout be + * inserted in the numerator (or denominator)? */ virtual bool mustHaveLeftBrother() const { return false; } virtual bool isHorizontal() const { return false; } virtual bool isLeftParenthesis() const { return false; } @@ -87,24 +110,24 @@ protected: virtual KDSize computeSize() = 0; virtual void computeBaseline() = 0; virtual KDPoint positionOfChild(ExpressionLayout * child) = 0; + ExpressionLayout * m_parent; + KDCoordinate m_baseline; + /* m_baseline is the signed vertical distance from the top of the layout to + * the fraction bar of an hypothetical fraction brother layout. If the top of + * the layout is under that bar, the baseline is negative. */ + bool m_sized; + bool m_baselined; + 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); - KDCoordinate m_baseline; - /* m_baseline is the signed vertical distance from the top of the layout to - * the fraction bar of an hypothetical fraction brother layout. If the top of - * the layout is under that bar, the baseline is negative. */ - ExpressionLayout * m_parent; - bool m_sized; - bool m_baselined; - bool m_positioned; -private: - bool moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor); - void replaceWithJuxtapositionOf(ExpressionLayout * firstLayout, ExpressionLayout * secondLayout); + ExpressionLayout * replaceWithJuxtapositionOf(ExpressionLayout * leftChild, ExpressionLayout * rightChild, bool deleteAfterReplace); KDRect m_frame; }; diff --git a/poincare/src/layout/expression_layout.cpp b/poincare/src/layout/expression_layout.cpp index f79a62e0e..76e7adcc4 100644 --- a/poincare/src/layout/expression_layout.cpp +++ b/poincare/src/layout/expression_layout.cpp @@ -10,8 +10,8 @@ namespace Poincare { ExpressionLayout::ExpressionLayout() : - m_baseline(0), m_parent(nullptr), + m_baseline(0), m_sized(false), m_baselined(false), m_positioned(false), @@ -19,6 +19,14 @@ ExpressionLayout::ExpressionLayout() : { } +void ExpressionLayout::draw(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) { + int i = 0; + while (ExpressionLayout * c = editableChild(i++)) { + c->draw(ctx, p, expressionColor, backgroundColor); + } + render(ctx, absoluteOrigin().translatedBy(p), expressionColor, backgroundColor); +} + KDPoint ExpressionLayout::origin() { if (m_parent == nullptr) { return absoluteOrigin(); @@ -28,14 +36,6 @@ KDPoint ExpressionLayout::origin() { } } -void ExpressionLayout::draw(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) { - int i = 0; - while (ExpressionLayout * c = editableChild(i++)) { - c->draw(ctx, p, expressionColor, backgroundColor); - } - render(ctx, absoluteOrigin().translatedBy(p), expressionColor, backgroundColor); -} - KDPoint ExpressionLayout::absoluteOrigin() { if (!m_positioned) { if (m_parent != nullptr) { @@ -83,7 +83,7 @@ const ExpressionLayout * ExpressionLayout::child(int i) const { return nullptr; } -int ExpressionLayout::indexOfChild(ExpressionLayout * child) const { +int ExpressionLayout::indexOfChild(const ExpressionLayout * child) const { if (child == nullptr) { return -1; } @@ -95,10 +95,6 @@ int ExpressionLayout::indexOfChild(ExpressionLayout * child) const { return -1; } -void ExpressionLayout::setParent(ExpressionLayout* parent) { - m_parent = parent; -} - bool ExpressionLayout::hasAncestor(const ExpressionLayout * e) const { assert(m_parent != this); if (m_parent == e) { @@ -143,28 +139,12 @@ void ExpressionLayout::addBrother(ExpressionLayoutCursor * cursor, ExpressionLay return; } -bool ExpressionLayout::insertLayoutAtCursor(ExpressionLayout * newChild, ExpressionLayoutCursor * cursor) { - cursor->pointedExpressionLayout()->addBrother(cursor, newChild); - return true; -} - ExpressionLayout * ExpressionLayout::replaceWith(ExpressionLayout * newChild, bool deleteAfterReplace) { assert(m_parent != nullptr); m_parent->replaceChild(this, newChild, deleteAfterReplace); return newChild; } -ExpressionLayout * ExpressionLayout::replaceWithJuxtapositionOf(ExpressionLayout * leftChild, ExpressionLayout * rightChild, bool deleteAfterReplace) { - assert(m_parent != nullptr); - /* One of the children to juxtapose might be "this", so we first have to - * replace "this" with an horizontal layout, then add "this" to the layout. */ - ExpressionLayout * layout = new HorizontalLayout(); - m_parent->replaceChild(this, layout, deleteAfterReplace); - layout->addChildAtIndex(leftChild, 0); - layout->addChildAtIndex(rightChild, 1); - return layout; -} - ExpressionLayout * ExpressionLayout::replaceWithAndMoveCursor(ExpressionLayout * newChild, bool deleteAfterReplace, ExpressionLayoutCursor * cursor) { assert(m_parent != nullptr); m_parent->replaceChildAndMoveCursor(this, newChild, deleteAfterReplace, cursor); @@ -199,7 +179,7 @@ void ExpressionLayout::replaceChild(const ExpressionLayout * oldChild, Expressio } void ExpressionLayout::replaceChildAndMoveCursor(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor) { - int oldChildIndex = indexOfChild(const_cast(oldChild)); + int oldChildIndex = indexOfChild(oldChild); assert(oldChildIndex >= 0); if (oldChildIndex == 0) { cursor->setPointedExpressionLayout(this); @@ -212,16 +192,12 @@ void ExpressionLayout::replaceChildAndMoveCursor(const ExpressionLayout * oldChi } void ExpressionLayout::detachChild(const ExpressionLayout * e) { - ExpressionLayout ** op = const_cast(children()); - for (int i = 0; i < numberOfChildren(); i++) { - if (op[i] == e) { - detachChildAtIndex(i); - } - } + assert(indexOfChild(e) >= 0); + detachChildAtIndex(indexOfChild(e)); } void ExpressionLayout::detachChildren() { - for (int i = 0; i setPointedExpressionLayout(editableChild(indexOfNewPointedLayout)); } + +bool ExpressionLayout::insertLayoutAtCursor(ExpressionLayout * newChild, ExpressionLayoutCursor * cursor) { + cursor->pointedExpressionLayout()->addBrother(cursor, newChild); + return true; +} + void ExpressionLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) { int indexOfPointedExpression = indexOfChild(cursor->pointedExpressionLayout()); if (indexOfPointedExpression >= 0) { @@ -302,17 +284,6 @@ char ExpressionLayout::XNTChar() const { return m_parent->XNTChar(); } -void ExpressionLayout::detachChildAtIndex(int i) { - ExpressionLayout ** op = const_cast(children()); - if (op[i] != nullptr && op[i]->parent() == this) { - const_cast(op[i])->setParent(nullptr); - } - op[i] = nullptr; - m_sized = false; - m_positioned = false; - m_baselined = false; -} - bool ExpressionLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) { if (m_parent) { return m_parent->moveUp(cursor, this, previousLayout); @@ -335,6 +306,17 @@ bool ExpressionLayout::moveDownInside(ExpressionLayoutCursor * cursor) { return moveInside(VerticalDirection::Down, cursor); } +void ExpressionLayout::detachChildAtIndex(int i) { + ExpressionLayout ** op = const_cast(children()); + if (op[i] != nullptr && op[i]->parent() == this) { + const_cast(op[i])->setParent(nullptr); + } + op[i] = nullptr; + m_sized = false; + m_positioned = false; + m_baselined = false; +} + bool ExpressionLayout::moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor) { ExpressionLayout * chilResult = nullptr; ExpressionLayout ** childResultPtr = &chilResult; @@ -391,4 +373,15 @@ void ExpressionLayout::moveCursorInsideAtDirection ( } } +ExpressionLayout * ExpressionLayout::replaceWithJuxtapositionOf(ExpressionLayout * leftChild, ExpressionLayout * rightChild, bool deleteAfterReplace) { + assert(m_parent != nullptr); + /* One of the children to juxtapose might be "this", so we first have to + * replace "this" with an horizontal layout, then add "this" to the layout. */ + ExpressionLayout * layout = new HorizontalLayout(); + m_parent->replaceChild(this, layout, deleteAfterReplace); + layout->addChildAtIndex(leftChild, 0); + layout->addChildAtIndex(rightChild, 1); + return layout; +} + } diff --git a/poincare/src/layout/horizontal_layout.cpp b/poincare/src/layout/horizontal_layout.cpp index 2f75b68e8..0bc3fc214 100644 --- a/poincare/src/layout/horizontal_layout.cpp +++ b/poincare/src/layout/horizontal_layout.cpp @@ -38,7 +38,7 @@ void HorizontalLayout::privateReplaceChild(const ExpressionLayout * oldChild, Ex if (newChild->hasAncestor(this)) { newChild->editableParent()->detachChild(newChild); } - int oldChildIndex = indexOfChild(const_cast(oldChild)); + int oldChildIndex = indexOfChild(oldChild); if (newChild->isEmpty()) { if (numberOfChildren() > 1) { // If the new layout is empty and the horizontal layout has other @@ -46,7 +46,7 @@ void HorizontalLayout::privateReplaceChild(const ExpressionLayout * oldChild, Ex if (!newChild->hasAncestor(oldChild)) { delete newChild; } - removeChildAtIndex(indexOfChild(const_cast(oldChild)), deleteOldChild); + removeChildAtIndex(oldChildIndex, deleteOldChild); if (cursor == nullptr) { return; } @@ -74,7 +74,7 @@ void HorizontalLayout::privateReplaceChild(const ExpressionLayout * oldChild, Ex // If the new child is also an horizontal layout, steal the children of the // new layout then destroy it. if (newChild->isHorizontal()) { - int indexForInsertion = indexOfChild(const_cast(oldChild)); + int indexForInsertion = indexOfChild(oldChild); mergeChildrenAtIndex(static_cast(newChild), indexForInsertion + 1, true); removeChildAtIndex(indexForInsertion, deleteOldChild); if (cursor == nullptr) { diff --git a/poincare/src/layout/matrix_layout.cpp b/poincare/src/layout/matrix_layout.cpp index eee2bcf42..f88ddb27c 100644 --- a/poincare/src/layout/matrix_layout.cpp +++ b/poincare/src/layout/matrix_layout.cpp @@ -18,13 +18,13 @@ ExpressionLayout * MatrixLayout::clone() const { } void MatrixLayout::replaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild) { - int oldChildIndex = indexOfChild(const_cast(oldChild)); + int oldChildIndex = indexOfChild(oldChild); GridLayout::replaceChild(oldChild, newChild, deleteOldChild); childWasReplacedAtIndex(oldChildIndex); } void MatrixLayout::replaceChildAndMoveCursor(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor) { - int oldChildIndex = indexOfChild(const_cast(oldChild)); + int oldChildIndex = indexOfChild(oldChild); int rowIndex = rowAtChildIndex(oldChildIndex); int columnIndex = columnAtChildIndex(oldChildIndex); replaceChild(oldChild, newChild, deleteOldChild);