[poincare] moveLeft renamed cursorOnLeft, same for other directions

Change-Id: Ic46604ea81eabdb2e10755a67307169d90654efd
This commit is contained in:
Léa Saviot
2018-04-20 15:39:35 +02:00
parent 1d6e0bb060
commit 9e87172800
38 changed files with 461 additions and 651 deletions

View File

@@ -12,6 +12,7 @@ public:
ExpressionViewWithCursor(Poincare::ExpressionLayout * expressionLayout);
bool isEditing() const { return m_isEditing; }
void setEditing(bool isEditing);
void setCursor(Poincare::ExpressionLayoutCursor cursor) { m_cursor = cursor; }
void cursorPositionChanged();
KDRect cursorRect();
Poincare::ExpressionLayoutCursor * cursor() { return &m_cursor; }

View File

@@ -2,6 +2,7 @@
#include <escher/clipboard.h>
#include <escher/text_field.h>
#include <poincare/src/layout/matrix_layout.h>
#include <poincare/expression_layout_cursor.h>
#include <assert.h>
ScrollableExpressionViewWithCursor::ScrollableExpressionViewWithCursor(Responder * parentResponder, Poincare::ExpressionLayout * expressionLayout, ScrollableExpressionViewWithCursorDelegate * delegate) :
@@ -79,26 +80,24 @@ KDSize ScrollableExpressionViewWithCursor::minimalSizeForOptimalDisplay() const
}
bool ScrollableExpressionViewWithCursor::privateHandleMoveEvent(Ion::Events::Event event, bool * shouldRecomputeLayout) {
Poincare::ExpressionLayoutCursor result;
if (event == Ion::Events::Left) {
return m_expressionViewWithCursor.cursor()->moveLeft(shouldRecomputeLayout);
result = m_expressionViewWithCursor.cursor()->cursorOnLeft(shouldRecomputeLayout);
} else if (event == Ion::Events::Right) {
result = m_expressionViewWithCursor.cursor()->cursorOnRight(shouldRecomputeLayout);
} else if (event == Ion::Events::Up) {
result = m_expressionViewWithCursor.cursor()->cursorAbove(shouldRecomputeLayout);
} else if (event == Ion::Events::Down) {
result = m_expressionViewWithCursor.cursor()->cursorUnder(shouldRecomputeLayout);
} else if (event == Ion::Events::ShiftLeft) {
result.setPointedExpressionLayout(m_expressionViewWithCursor.expressionView()->expressionLayout());
result.setPosition(Poincare::ExpressionLayoutCursor::Position::Left);
} else if (event == Ion::Events::ShiftRight) {
result.setPointedExpressionLayout(m_expressionViewWithCursor.expressionView()->expressionLayout());
result.setPosition(Poincare::ExpressionLayoutCursor::Position::Right);
}
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);
if (result.isDefined()) {
m_expressionViewWithCursor.setCursor(result);
return true;
}
return false;

View File

@@ -80,12 +80,12 @@ public:
virtual void deleteBeforeCursor(ExpressionLayoutCursor * cursor);
/* Tree navigation */
virtual bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) = 0;
virtual bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) = 0;
virtual bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false);
virtual bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false);
virtual bool moveUpInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout);
virtual bool moveDownInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout);
virtual ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) = 0;
virtual ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) = 0;
virtual ExpressionLayoutCursor cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false);
virtual ExpressionLayoutCursor cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false);
virtual ExpressionLayoutCursor cursorInDescendantsAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout);
virtual ExpressionLayoutCursor cursorInDescendantsUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout);
/* Expression Engine */
virtual int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const = 0;
@@ -128,7 +128,7 @@ protected:
virtual KDSize computeSize() = 0;
virtual void computeBaseline() = 0;
virtual KDPoint positionOfChild(ExpressionLayout * child) = 0;
void moveCursorInsideAtDirection (
void scoreCursorInDescendantsVerticalOf (
VerticalDirection direction,
ExpressionLayoutCursor * cursor,
bool * shouldRecomputeLayout,
@@ -147,8 +147,8 @@ protected:
bool m_positioned;
private:
void detachChildAtIndex(int i);
bool moveVertically(VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited);
bool moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout);
ExpressionLayoutCursor cursorVerticalOf(VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited);
ExpressionLayoutCursor cursorInDescendantsVerticalOf(VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout);
ExpressionLayout * replaceWithJuxtapositionOf(ExpressionLayout * leftChild, ExpressionLayout * rightChild, bool deleteAfterReplace);
KDRect m_frame;
};

View File

@@ -38,10 +38,10 @@ public:
KDPoint middleLeftPoint();
/* Move */
bool moveLeft(bool * shouldRecomputeLayout);
bool moveRight(bool * shouldRecomputeLayout);
bool moveUp(bool * shouldRecomputeLayout);
bool moveDown(bool * shouldRecomputeLayout);
ExpressionLayoutCursor cursorOnLeft(bool * shouldRecomputeLayout);
ExpressionLayoutCursor cursorOnRight(bool * shouldRecomputeLayout);
ExpressionLayoutCursor cursorAbove(bool * shouldRecomputeLayout);
ExpressionLayoutCursor cursorUnder(bool * shouldRecomputeLayout);
/* Edition */
void addLayoutAndMoveCursor(ExpressionLayout * layout);

View File

@@ -47,20 +47,20 @@ KDPoint ExpressionLayoutCursor::middleLeftPoint() {
return KDPoint(x, y);
}
bool ExpressionLayoutCursor::moveLeft(bool * shouldRecomputeLayout) {
return m_pointedExpressionLayout->moveLeft(this, shouldRecomputeLayout);
ExpressionLayoutCursor ExpressionLayoutCursor::cursorOnLeft(bool * shouldRecomputeLayout) {
return m_pointedExpressionLayout->cursorLeftOf(this, shouldRecomputeLayout);
}
bool ExpressionLayoutCursor::moveRight(bool * shouldRecomputeLayout) {
return m_pointedExpressionLayout->moveRight(this, shouldRecomputeLayout);
ExpressionLayoutCursor ExpressionLayoutCursor::cursorOnRight(bool * shouldRecomputeLayout) {
return m_pointedExpressionLayout->cursorRightOf(this, shouldRecomputeLayout);
}
bool ExpressionLayoutCursor::moveUp(bool * shouldRecomputeLayout) {
return m_pointedExpressionLayout->moveUp(this, shouldRecomputeLayout);
ExpressionLayoutCursor ExpressionLayoutCursor::cursorAbove(bool * shouldRecomputeLayout) {
return m_pointedExpressionLayout->cursorAbove(this, shouldRecomputeLayout);
}
bool ExpressionLayoutCursor::moveDown(bool * shouldRecomputeLayout) {
return m_pointedExpressionLayout->moveDown(this, shouldRecomputeLayout);
ExpressionLayoutCursor ExpressionLayoutCursor::cursorUnder(bool * shouldRecomputeLayout) {
return m_pointedExpressionLayout->cursorUnder(this, shouldRecomputeLayout);
}
void ExpressionLayoutCursor::addLayoutAndMoveCursor(ExpressionLayout * layout) {

View File

@@ -18,80 +18,67 @@ ExpressionLayout * BinomialCoefficientLayout::clone() const {
return new BinomialCoefficientLayout(const_cast<BinomialCoefficientLayout *>(this)->nLayout(), const_cast<BinomialCoefficientLayout *>(this)->kLayout(), true);
}
bool BinomialCoefficientLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the children.
// Go Left.
ExpressionLayoutCursor BinomialCoefficientLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the children. Go Left.
if (cursor->position() == ExpressionLayoutCursor::Position::Left
&& (cursor->pointedExpressionLayout() == nLayout()
|| cursor->pointedExpressionLayout() == kLayout()))
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Go to the kLayout.
// Case: Right. Go to the kLayout.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
assert(kLayout() != nullptr);
cursor->setPointedExpressionLayout(kLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(kLayout(), ExpressionLayoutCursor::Position::Right);
}
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool BinomialCoefficientLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the children.
// Go Right.
ExpressionLayoutCursor BinomialCoefficientLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the children. Go Right.
if (cursor->position() == ExpressionLayoutCursor::Position::Right
&& (cursor->pointedExpressionLayout() == nLayout()
|| cursor->pointedExpressionLayout() == kLayout()))
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Go Left of the nLayout.
// Case: Left. Go Left of the nLayout.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
assert(nLayout() != nullptr);
cursor->setPointedExpressionLayout(nLayout());
return true;
return ExpressionLayoutCursor(nLayout(), ExpressionLayoutCursor::Position::Left);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool BinomialCoefficientLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// Case: kLayout.
// Move to nLayout.
ExpressionLayoutCursor BinomialCoefficientLayout::cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// Case: kLayout. Move to nLayout.
if (cursor->pointedExpressionLayout()->hasAncestor(kLayout(), true)) {
return nLayout()->moveUpInside(cursor, shouldRecomputeLayout);
return nLayout()->cursorInDescendantsAbove(cursor, shouldRecomputeLayout);
}
return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorAbove(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
bool BinomialCoefficientLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// Case: nLayout.
// Move to kLayout.
ExpressionLayoutCursor BinomialCoefficientLayout::cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// Case: nLayout. Move to kLayout.
if (cursor->pointedExpressionLayout()->hasAncestor(nLayout(), true)) {
return kLayout()->moveDownInside(cursor, shouldRecomputeLayout);
return kLayout()->cursorInDescendantsUnder(cursor, shouldRecomputeLayout);
}
return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorUnder(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
void BinomialCoefficientLayout::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {

View File

@@ -11,10 +11,10 @@ class BinomialCoefficientLayout : public StaticLayoutHierarchy<2> {
public:
using StaticLayoutHierarchy::StaticLayoutHierarchy;
ExpressionLayout * clone() const override;
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override {
return LayoutEngine::writePrefixExpressionLayoutTextInBuffer(this, buffer, bufferSize, numberOfSignificantDigits, "binomial");
}

View File

@@ -18,41 +18,34 @@ void BracketLayout::invalidAllSizesPositionsAndBaselines() {
ExpressionLayout::invalidAllSizesPositionsAndBaselines();
}
bool BracketLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor BracketLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Go Left.
// Case: Right. Go Left.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool BracketLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor BracketLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Go Right.
// Case: Left. Go Right.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
KDSize BracketLayout::computeSize() {
return KDSize(k_externWidthMargin + k_lineThickness + k_widthMargin, operandHeight() + k_lineThickness);
}

View File

@@ -9,8 +9,8 @@ class BracketLayout : public StaticLayoutHierarchy<0> {
public:
BracketLayout();
void invalidAllSizesPositionsAndBaselines() override;
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
protected:
constexpr static KDCoordinate k_bracketWidth = 5;
constexpr static KDCoordinate k_lineThickness = 1;

View File

@@ -34,59 +34,49 @@ void BracketPairLayout::deleteBeforeCursor(ExpressionLayoutCursor * cursor) {
ExpressionLayout::deleteBeforeCursor(cursor);
}
bool BracketPairLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the operand.
// Go Left of the brackets.
ExpressionLayoutCursor BracketPairLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the operand. Go Left of the brackets.
if (operandLayout()
&& cursor->pointedExpressionLayout() == operandLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Right of the brackets.
// Go Right of the operand.
// Case: Right of the brackets. Go Right of the operand.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
assert(operandLayout() != nullptr);
cursor->setPointedExpressionLayout(operandLayout());
return true;
return ExpressionLayoutCursor(operandLayout(), ExpressionLayoutCursor::Position::Right);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
// Case: Left of the brackets.
// Ask the parent.
// Case: Left of the brackets. Ask the parent.
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool BracketPairLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the operand.
// Go Right of the brackets.
ExpressionLayoutCursor BracketPairLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the operand. Go Right of the brackets.
if (operandLayout()
&& cursor->pointedExpressionLayout() == operandLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Left of the brackets.
// Go Left of the operand.
// Case: Left of the brackets. Go Left of the operand.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
assert(operandLayout() != nullptr);
cursor->setPointedExpressionLayout(operandLayout());
return true;
return ExpressionLayoutCursor(operandLayout(), ExpressionLayoutCursor::Position::Left);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
// Case: Right of the brackets.
// Ask the parent.
// Case: Right of the brackets. Ask the parent.
cursor->setPointedExpressionLayout(this);
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
int BracketPairLayout::writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits) const {

View File

@@ -13,8 +13,8 @@ public:
ExpressionLayout * clone() const override;
void collapseSiblingsAndMoveCursor(ExpressionLayoutCursor * cursor) override;
void deleteBeforeCursor(ExpressionLayoutCursor * cursor) override;
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override;
protected:
ExpressionLayout * operandLayout();

View File

@@ -18,36 +18,30 @@ ExpressionLayout * CharLayout::clone() const {
return layout;
}
bool CharLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor CharLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Go Left.
// Case: Right. Go Left.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool CharLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor CharLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Go Right.
// Case: Left. Go Right.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool CharLayout::isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const {

View File

@@ -17,8 +17,8 @@ public:
char character() { return m_char; }
KDText::FontSize fontSize() const { return m_fontSize; }
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const override;
protected:
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override;

View File

@@ -10,58 +10,46 @@ ExpressionLayout * CondensedSumLayout::clone() const {
return layout;
}
bool CondensedSumLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the bounds.
// Go Left of the sum.
ExpressionLayoutCursor CondensedSumLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the bounds. Go Left of the sum.
if (((subscriptLayout() && cursor->pointedExpressionLayout() == subscriptLayout())
|| (superscriptLayout() && cursor->pointedExpressionLayout() == superscriptLayout()))
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
cursor->setPointedExpressionLayout(this);
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
// Case: Left of the base.
// Go Right of the lower bound.
// Case: Left of the base. Go Right of the lower bound.
if (baseLayout()
&& cursor->pointedExpressionLayout() == baseLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
cursor->setPointedExpressionLayout(subscriptLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(subscriptLayout(), ExpressionLayoutCursor::Position::Right);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Go to the base and move Left.
// Case: Right. Go to the base and move Left.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
assert(baseLayout());
cursor->setPointedExpressionLayout(baseLayout());
return baseLayout()->moveLeft(cursor, shouldRecomputeLayout);
return baseLayout()->cursorLeftOf(cursor, shouldRecomputeLayout);
}
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool CondensedSumLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the bounds.
// Go Left of the operand.
ExpressionLayoutCursor CondensedSumLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the bounds. Go Left of the operand.
if (((subscriptLayout() && cursor->pointedExpressionLayout() == subscriptLayout())
|| (superscriptLayout() && cursor->pointedExpressionLayout() == superscriptLayout()))
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
assert(baseLayout() != nullptr);
cursor->setPointedExpressionLayout(baseLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
}
// Case: Right of the base.
// Ask the parent.
return ExpressionLayoutCursor(baseLayout(), ExpressionLayoutCursor::Position::Left);
}
// Case: Right of the base. Ask the parent.
if (baseLayout()
&& cursor->pointedExpressionLayout() == baseLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
@@ -69,53 +57,50 @@ bool CondensedSumLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shoul
cursor->setPointedExpressionLayout(this);
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Go to the upper bound.
// Case: Left. Go to the upper bound.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
assert(superscriptLayout());
cursor->setPointedExpressionLayout(superscriptLayout());
return true;
return ExpressionLayoutCursor(superscriptLayout(), ExpressionLayoutCursor::Position::Left);
}
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool CondensedSumLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor CondensedSumLayout::cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// If the cursor is inside the subscript layout, move it to the superscript.
if (subscriptLayout() && cursor->pointedExpressionLayout()->hasAncestor(subscriptLayout(), true)) {
assert(superscriptLayout() != nullptr);
return superscriptLayout()->moveUpInside(cursor, shouldRecomputeLayout);
return superscriptLayout()->cursorInDescendantsAbove(cursor, shouldRecomputeLayout);
}
// If the cursor is Left of the base layout, move it to the superscript.
if (baseLayout() && cursor->isEquivalentTo(ExpressionLayoutCursor(baseLayout(), ExpressionLayoutCursor::Position::Left))) {
assert(superscriptLayout() != nullptr);
return superscriptLayout()->moveUpInside(cursor, shouldRecomputeLayout);
return superscriptLayout()->cursorInDescendantsAbove(cursor, shouldRecomputeLayout);
}
return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorAbove(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
bool CondensedSumLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor CondensedSumLayout::cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// If the cursor is inside the superscript layout, move it to the subscript.
if (superscriptLayout() && cursor->pointedExpressionLayout()->hasAncestor(superscriptLayout(), true)) {
assert(subscriptLayout() != nullptr);
return subscriptLayout()->moveUpInside(cursor, shouldRecomputeLayout);
return subscriptLayout()->cursorInDescendantsUnder(cursor, shouldRecomputeLayout);
}
// If the cursor is Left of the base layout, move it to the subscript.
if (baseLayout() && cursor->isEquivalentTo(ExpressionLayoutCursor(baseLayout(), ExpressionLayoutCursor::Position::Left))) {
assert(subscriptLayout() != nullptr);
return subscriptLayout()->moveUpInside(cursor, shouldRecomputeLayout);
return subscriptLayout()->cursorInDescendantsUnder(cursor, shouldRecomputeLayout);
}
return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorUnder(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
ExpressionLayout * CondensedSumLayout::layoutToPointWhenInserting() {

View File

@@ -10,10 +10,10 @@ class CondensedSumLayout : public StaticLayoutHierarchy<3> {
public:
using StaticLayoutHierarchy::StaticLayoutHierarchy;
ExpressionLayout * clone() const override;
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override {
return LayoutEngine::writePrefixExpressionLayoutTextInBuffer(this, buffer, bufferSize, numberOfSignificantDigits, "sum");
}

View File

@@ -26,58 +26,48 @@ void ConjugateLayout::collapseSiblingsAndMoveCursor(ExpressionLayoutCursor * cur
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
}
bool ConjugateLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the operand.
// Move Left.
ExpressionLayoutCursor ConjugateLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the operand. Move Left.
if (operandLayout()
&& cursor->pointedExpressionLayout() == operandLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Go to the operand.
// Case: Right. Go to the operand.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
assert(operandLayout() != nullptr);
cursor->setPointedExpressionLayout(operandLayout());
return true;
return ExpressionLayoutCursor(operandLayout(), ExpressionLayoutCursor::Position::Right);
}
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool ConjugateLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the operand.
// Move Right.
ExpressionLayoutCursor ConjugateLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the operand. Move Right.
if (operandLayout()
&& cursor->pointedExpressionLayout() == operandLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Go to the operand.
// Case: Left. Go to the operand.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
assert(operandLayout() != nullptr);
cursor->setPointedExpressionLayout(operandLayout());
return true;
return ExpressionLayoutCursor(operandLayout(), ExpressionLayoutCursor::Position::Left);
}
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
void ConjugateLayout::replaceChildAndMoveCursor(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor) {

View File

@@ -11,8 +11,8 @@ public:
using StaticLayoutHierarchy::StaticLayoutHierarchy;
ExpressionLayout * clone() const override;
void collapseSiblingsAndMoveCursor(ExpressionLayoutCursor * cursor) override;
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) 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, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override {

View File

@@ -25,24 +25,24 @@ void EmptyLayout::deleteBeforeCursor(ExpressionLayoutCursor * cursor) {
}
}
bool EmptyLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor EmptyLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
assert(cursor->pointedExpressionLayout() == this);
// Ask the parent.
if (m_parent) {
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool EmptyLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor EmptyLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
assert(cursor->pointedExpressionLayout() == this);
// Ask the parent.
if (m_parent) {
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
int EmptyLayout::writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits) const {

View File

@@ -15,8 +15,8 @@ public:
EmptyLayout(Color color = Color::Yellow, bool visible = true);
ExpressionLayout * clone() const override;
void deleteBeforeCursor(ExpressionLayoutCursor * cursor) override;
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override;
bool isEmpty() const override { return true; }
Color color() const { return m_color; }

View File

@@ -209,7 +209,7 @@ void ExpressionLayout::deleteBeforeCursor(ExpressionLayoutCursor * cursor) {
// Case: The pointed layout is a child. Move Left.
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
bool shouldRecomputeLayout = false;
cursor->moveLeft(&shouldRecomputeLayout);
cursor->cursorOnLeft(&shouldRecomputeLayout);
return;
}
assert(cursor->pointedExpressionLayout() == this);
@@ -237,20 +237,20 @@ char ExpressionLayout::XNTChar() const {
return m_parent->XNTChar();
}
bool ExpressionLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
return moveVertically(VerticalDirection::Up, cursor, shouldRecomputeLayout, equivalentPositionVisited);
ExpressionLayoutCursor ExpressionLayout::cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
return cursorVerticalOf(VerticalDirection::Up, cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
bool ExpressionLayout::moveUpInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
return moveInside(VerticalDirection::Up, cursor, shouldRecomputeLayout);
ExpressionLayoutCursor ExpressionLayout::cursorInDescendantsAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
return cursorInDescendantsVerticalOf(VerticalDirection::Up, cursor, shouldRecomputeLayout);
}
bool ExpressionLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
return moveVertically(VerticalDirection::Down, cursor, shouldRecomputeLayout, equivalentPositionVisited);
ExpressionLayoutCursor ExpressionLayout::cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
return cursorVerticalOf(VerticalDirection::Down, cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
bool ExpressionLayout::moveDownInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
return moveInside(VerticalDirection::Down, cursor, shouldRecomputeLayout);
ExpressionLayoutCursor ExpressionLayout::cursorInDescendantsUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
return cursorInDescendantsVerticalOf(VerticalDirection::Down, cursor, shouldRecomputeLayout);
}
ExpressionLayoutCursor ExpressionLayout::equivalentCursor(ExpressionLayoutCursor * cursor) {
@@ -317,7 +317,7 @@ void ExpressionLayout::detachChildAtIndex(int i) {
m_baselined = false;
}
bool ExpressionLayout::moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor ExpressionLayout::cursorInDescendantsVerticalOf(VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayout * chilResult = nullptr;
ExpressionLayout ** childResultPtr = &chilResult;
ExpressionLayoutCursor::Position resultPosition = ExpressionLayoutCursor::Position::Left;
@@ -325,42 +325,40 @@ 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, shouldRecomputeLayout, childResultPtr, &resultPosition, &resultScore);
scoreCursorInDescendantsVerticalOf(direction, cursor, shouldRecomputeLayout, childResultPtr, &resultPosition, &resultScore);
// If there is a valid result
if (*childResultPtr == nullptr) {
return false;
return ExpressionLayoutCursor();
}
cursor->setPointedExpressionLayout(*childResultPtr);
cursor->setPosition(resultPosition);
*shouldRecomputeLayout = (*childResultPtr)->addGreySquaresToAllMatrixAncestors();
return true;
return ExpressionLayoutCursor(*childResultPtr, resultPosition);
}
bool ExpressionLayout::moveVertically(VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor ExpressionLayout::cursorVerticalOf(VerticalDirection direction, ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
if (!equivalentPositionVisited) {
ExpressionLayoutCursor cursorEquivalent = equivalentCursor(cursor);
if (cursorEquivalent.isDefined()) {
cursor->setPointedExpressionLayout(cursorEquivalent.pointedExpressionLayout());
cursor->setPosition(cursorEquivalent.position());
if (direction == VerticalDirection::Up) {
return cursor->pointedExpressionLayout()->moveUp(cursor, shouldRecomputeLayout, true);
return cursor->pointedExpressionLayout()->cursorAbove(cursor, shouldRecomputeLayout, true);
} else {
return cursor->pointedExpressionLayout()->moveDown(cursor, shouldRecomputeLayout, true);
return cursor->pointedExpressionLayout()->cursorUnder(cursor, shouldRecomputeLayout, true);
}
}
}
if (m_parent) {
if (direction == VerticalDirection::Up) {
return m_parent->moveUp(cursor, shouldRecomputeLayout, true);
return m_parent->cursorAbove(cursor, shouldRecomputeLayout, true);
} else {
return m_parent->moveDown(cursor, shouldRecomputeLayout, true);
return m_parent->cursorUnder(cursor, shouldRecomputeLayout, true);
}
}
return false;
return ExpressionLayoutCursor();
}
void ExpressionLayout::moveCursorInsideAtDirection (
void ExpressionLayout::scoreCursorInDescendantsVerticalOf (
VerticalDirection direction,
ExpressionLayoutCursor * cursor,
bool * shouldRecomputeLayout,
@@ -393,7 +391,7 @@ void ExpressionLayout::moveCursorInsideAtDirection (
if (layoutIsUnderOrAbove || layoutContains) {
int childIndex = 0;
while (child(childIndex++)) {
editableChild(childIndex-1)->moveCursorInsideAtDirection(direction, cursor, shouldRecomputeLayout, childResult, castedResultPosition, resultScore);
editableChild(childIndex-1)->scoreCursorInDescendantsVerticalOf(direction, cursor, shouldRecomputeLayout, childResult, castedResultPosition, resultScore);
}
}
}

View File

@@ -89,86 +89,76 @@ void FractionLayout::deleteBeforeCursor(ExpressionLayoutCursor * cursor) {
ExpressionLayout::deleteBeforeCursor(cursor);
}
bool FractionLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the numerator or the denominator.
// Go Left of the fraction.
ExpressionLayoutCursor FractionLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the numerator or the denominator. Go Left of the fraction.
if (((numeratorLayout() && cursor->pointedExpressionLayout() == numeratorLayout())
|| (denominatorLayout() && cursor->pointedExpressionLayout() == denominatorLayout()))
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Go to the denominator.
// Case: Right. Go to the denominator.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
assert(denominatorLayout() != nullptr);
cursor->setPointedExpressionLayout(denominatorLayout());
return true;
return ExpressionLayoutCursor(denominatorLayout(), ExpressionLayoutCursor::Position::Right);
}
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool FractionLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the numerator or the denominator.
// Go Right of the fraction.
ExpressionLayoutCursor FractionLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the numerator or the denominator. Go Right of the fraction.
if (((numeratorLayout() && cursor->pointedExpressionLayout() == numeratorLayout())
|| (denominatorLayout() && cursor->pointedExpressionLayout() == denominatorLayout()))
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Go to the numerator.
// Case: Left. Go to the numerator.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
assert(numeratorLayout() != nullptr);
cursor->setPointedExpressionLayout(numeratorLayout());
return true;
return ExpressionLayoutCursor(numeratorLayout(), ExpressionLayoutCursor::Position::Left);
}
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool FractionLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor FractionLayout::cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// If the cursor is inside denominator, move it to the numerator.
if (denominatorLayout() && cursor->pointedExpressionLayout()->hasAncestor(denominatorLayout(), true)) {
assert(numeratorLayout() != nullptr);
return numeratorLayout()->moveUpInside(cursor, shouldRecomputeLayout);
return numeratorLayout()->cursorInDescendantsAbove(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, shouldRecomputeLayout);
return numeratorLayout()->cursorInDescendantsAbove(cursor, shouldRecomputeLayout);
}
return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorAbove(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
bool FractionLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor FractionLayout::cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// If the cursor is inside numerator, move it to the denominator.
if (numeratorLayout() && cursor->pointedExpressionLayout()->hasAncestor(numeratorLayout(), true)) {
assert(denominatorLayout() != nullptr);
return denominatorLayout()->moveDownInside(cursor, shouldRecomputeLayout);
return denominatorLayout()->cursorInDescendantsUnder(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, shouldRecomputeLayout);
return denominatorLayout()->cursorInDescendantsUnder(cursor, shouldRecomputeLayout);
}
return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorUnder(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
int FractionLayout::writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits) const {

View File

@@ -12,10 +12,10 @@ public:
ExpressionLayout * clone() const override;
void collapseSiblingsAndMoveCursor(ExpressionLayoutCursor * cursor) override;
void deleteBeforeCursor(ExpressionLayoutCursor * cursor) override;
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override;
ExpressionLayout * layoutToPointWhenInserting() override;
bool canBeOmittedMultiplicationRightFactor() const override { return false; }

View File

@@ -21,101 +21,83 @@ ExpressionLayout * GridLayout::clone() const {
return layout;
}
bool GridLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right.
// Go to the last entry.
ExpressionLayoutCursor GridLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right. Go to the last entry.
if (cursor->pointedExpressionLayout() == this
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
ExpressionLayout * lastChild = editableChild(m_numberOfColumns*m_numberOfRows-1);
assert(lastChild != nullptr);
cursor->setPointedExpressionLayout(lastChild);
return true;
return ExpressionLayoutCursor(lastChild, ExpressionLayoutCursor::Position::Right);
}
// Case: The cursor points to a grid's child.
int childIndex = indexOfChild(cursor->pointedExpressionLayout());
if (childIndex >- 1 && cursor->position() == ExpressionLayoutCursor::Position::Left) {
if (childIsLeftOfGrid(childIndex)) {
// Case: Left of a child on the left of the grid.
// Go Left of the grid
cursor->setPointedExpressionLayout(this);
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
// Case: Left of a child on the left of the grid. Go Left of the grid
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
// Case: Left of another child.
// Go Right of its sibling on the left.
cursor->setPointedExpressionLayout(editableChild(childIndex-1));
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
// Case: Left of another child. Go Right of its sibling on the left.
return ExpressionLayoutCursor(editableChild(childIndex-1), ExpressionLayoutCursor::Position::Right);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool GridLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left.
// Go to the first entry.
ExpressionLayoutCursor GridLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left. Go to the first entry.
if (cursor->pointedExpressionLayout() == this
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
assert(m_numberOfColumns*m_numberOfRows >= 1);
ExpressionLayout * firstChild = editableChild(0);
assert(firstChild != nullptr);
cursor->setPointedExpressionLayout(firstChild);
return true;
}
return ExpressionLayoutCursor(firstChild, ExpressionLayoutCursor::Position::Left);
}
// Case: The cursor points to a grid's child.
int childIndex = indexOfChild(cursor->pointedExpressionLayout());
if (childIndex >- 1 && cursor->position() == ExpressionLayoutCursor::Position::Right) {
if (childIsRightOfGrid(childIndex)) {
// Case: Right of a child on the right of the grid.
// Go Right of the grid.
cursor->setPointedExpressionLayout(this);
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
// Case: Right of a child on the right of the grid. Go Right of the grid.
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
// Case: Right of another child.
// Go Left of its sibling on the right.
cursor->setPointedExpressionLayout(editableChild(childIndex+1));
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
// Case: Right of another child. Go Left of its sibling on the right.
return ExpressionLayoutCursor(editableChild(childIndex+1), ExpressionLayoutCursor::Position::Left);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool GridLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// If the cursor is child that is not on the top row, move it inside the upper
// neighbourg.
ExpressionLayoutCursor GridLayout::cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
/* If the cursor is child that is not on the top row, move it inside its upper
* neighbour.*/
int childIndex = m_numberOfColumns;
while (childIndex < numberOfChildren()) {
if (cursor->pointedExpressionLayout()->hasAncestor(child(childIndex), true)) {
return editableChild(childIndex - m_numberOfColumns)->moveUpInside(cursor, shouldRecomputeLayout);
return editableChild(childIndex - m_numberOfColumns)->cursorInDescendantsAbove(cursor, shouldRecomputeLayout);
}
childIndex++;
}
return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorAbove(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
bool GridLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor GridLayout::cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
int childIndex = 0;
while (childIndex < numberOfChildren() - m_numberOfColumns) {
if (cursor->pointedExpressionLayout()->hasAncestor(child(childIndex), true)) {
return editableChild(childIndex + m_numberOfColumns)->moveDownInside(cursor, shouldRecomputeLayout);
return editableChild(childIndex + m_numberOfColumns)->cursorInDescendantsUnder(cursor, shouldRecomputeLayout);
}
childIndex++;
}
return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorUnder(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
void GridLayout::removeChildAtIndex(int index, bool deleteAfterRemoval) {

View File

@@ -13,10 +13,10 @@ public:
ExpressionLayout * clone() const override;
/* Navigation */
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
/* Dynamic layout */
void removeChildAtIndex(int index, bool deleteAfterRemoval) override;

View File

@@ -171,14 +171,14 @@ void HorizontalLayout::addOrMergeChildAtIndex(ExpressionLayout * eL, int index,
addChildAtIndex(eL, index);
}
bool HorizontalLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor HorizontalLayout::cursorLeftOf(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, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
/* Case: Right.
@@ -187,14 +187,14 @@ bool HorizontalLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRe
if (numberOfChildren() < 1) {
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
ExpressionLayout * lastChild = editableChild(numberOfChildren()-1);
assert(lastChild != nullptr);
cursor->setPointedExpressionLayout(lastChild);
return lastChild->moveLeft(cursor, shouldRecomputeLayout);
return lastChild->cursorLeftOf(cursor, shouldRecomputeLayout);
}
// Case: The cursor is Left of a child.
@@ -205,24 +205,24 @@ bool HorizontalLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRe
// Case: the child is the leftmost. Ask the parent.
if (m_parent) {
cursor->setPointedExpressionLayout(this);
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
// Case: the child is not the leftmost. Go to its left sibling and move Left.
cursor->setPointedExpressionLayout(editableChild(childIndex-1));
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return editableChild(childIndex-1)->moveLeft(cursor, shouldRecomputeLayout);
return editableChild(childIndex-1)->cursorLeftOf(cursor, shouldRecomputeLayout);
}
bool HorizontalLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor HorizontalLayout::cursorRightOf(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, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
/* Case: Left.
@@ -231,14 +231,14 @@ bool HorizontalLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldR
if (numberOfChildren() < 1) {
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
ExpressionLayout * firstChild = editableChild(0);
assert(firstChild != nullptr);
cursor->setPointedExpressionLayout(firstChild);
return firstChild->moveRight(cursor, shouldRecomputeLayout);
return firstChild->cursorRightOf(cursor, shouldRecomputeLayout);
}
// Case: The cursor is Right of a child.
@@ -246,19 +246,18 @@ bool HorizontalLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldR
int childIndex = indexOfChild(cursor->pointedExpressionLayout());
assert(childIndex >= 0);
if (childIndex == numberOfChildren() - 1) {
// Case: the child is the rightmost.
// Ask the parent.
// Case: the child is the rightmost. Ask the parent.
if (m_parent) {
cursor->setPointedExpressionLayout(this);
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
/* Case: the child is not the rightmost. Go to its right sibling and move
* Right. */
cursor->setPointedExpressionLayout(editableChild(childIndex+1));
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return editableChild(childIndex+1)->moveRight(cursor, shouldRecomputeLayout);
return editableChild(childIndex+1)->cursorRightOf(cursor, shouldRecomputeLayout);
}
void HorizontalLayout::addChildrenAtIndex(const ExpressionLayout * const * operands, int numberOfOperands, int indexForInsertion, bool removeEmptyChildren) {

View File

@@ -23,8 +23,8 @@ public:
void addOrMergeChildAtIndex(ExpressionLayout * eL, int index, bool removeEmptyChildren);
/* Navigation */
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
/* Dynamic layout */
void addChildrenAtIndex(const ExpressionLayout * const * operands, int numberOfOperands, int indexForInsertion, bool removeEmptyChildren) override;

View File

@@ -36,47 +36,39 @@ void IntegralLayout::deleteBeforeCursor(ExpressionLayoutCursor * cursor) {
ExpressionLayout::deleteBeforeCursor(cursor);
}
bool IntegralLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left the upper or lower bound.
// Go Left of the integral.
ExpressionLayoutCursor IntegralLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left the upper or lower bound. Go Left of the integral.
if (((upperBoundLayout()
&& cursor->pointedExpressionLayout() == upperBoundLayout())
|| (lowerBoundLayout()
&& cursor->pointedExpressionLayout() == lowerBoundLayout()))
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
// Case: Left the integrand.
// Go Right of the lower bound.
// Case: Left the integrand. Go Right of the lower bound.
if (integrandLayout()
&& cursor->pointedExpressionLayout() == integrandLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
assert(lowerBoundLayout() != nullptr);
cursor->setPointedExpressionLayout(lowerBoundLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(lowerBoundLayout(), ExpressionLayoutCursor::Position::Right);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Right of the integral.
// Go to the integrand.
// Case: Right of the integral. Go to the integrand.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
assert(integrandLayout() != nullptr);
cursor->setPointedExpressionLayout(integrandLayout());
return true;
return ExpressionLayoutCursor(integrandLayout(), ExpressionLayoutCursor::Position::Right);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
// Case: Left of the brackets.
// Ask the parent.
// Case: Left of the brackets. Ask the parent.
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool IntegralLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor IntegralLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right the upper or lower bound.
// Go Left of the integrand.
if (((upperBoundLayout()
@@ -86,66 +78,59 @@ bool IntegralLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRec
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
assert(integrandLayout() != nullptr);
cursor->setPointedExpressionLayout(integrandLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(integrandLayout(), ExpressionLayoutCursor::Position::Left);
}
// Case: Right the integrand.
// Go Right.
// Case: Right the integrand. Go Right.
if (integrandLayout()
&& cursor->pointedExpressionLayout() == integrandLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Left of the integral.
// Go to the upper bound.
// Case: Left of the integral. Go to the upper bound.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
assert(upperBoundLayout() != nullptr);
cursor->setPointedExpressionLayout(upperBoundLayout());
return true;
return ExpressionLayoutCursor(upperBoundLayout(), ExpressionLayoutCursor::Position::Left);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool IntegralLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor IntegralLayout::cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// If the cursor is inside the lower bound, move it to the upper bound.
if (lowerBoundLayout() && cursor->pointedExpressionLayout()->hasAncestor(lowerBoundLayout(), true)) {
assert(upperBoundLayout() != nullptr);
return upperBoundLayout()->moveUpInside(cursor, shouldRecomputeLayout);
return upperBoundLayout()->cursorInDescendantsAbove(cursor, shouldRecomputeLayout);
}
// If the cursor is Left of the integrand, move it to the upper bound.
if (integrandLayout()
&& cursor->isEquivalentTo(ExpressionLayoutCursor(integrandLayout(), ExpressionLayoutCursor::Position::Left)))
{
assert(upperBoundLayout() != nullptr);
return upperBoundLayout()->moveUpInside(cursor, shouldRecomputeLayout);
return upperBoundLayout()->cursorInDescendantsAbove(cursor, shouldRecomputeLayout);
}
return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorAbove(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
bool IntegralLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor IntegralLayout::cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// If the cursor is inside the upper bound, move it to the lower bound.
if (upperBoundLayout() && cursor->pointedExpressionLayout()->hasAncestor(upperBoundLayout(), true)) {
assert(lowerBoundLayout() != nullptr);
return lowerBoundLayout()->moveDownInside(cursor, shouldRecomputeLayout);
return lowerBoundLayout()->cursorInDescendantsUnder(cursor, shouldRecomputeLayout);
}
// If the cursor is Left of the integrand, move it to the lower bound.
if (integrandLayout()
&& cursor->isEquivalentTo(ExpressionLayoutCursor(integrandLayout(), ExpressionLayoutCursor::Position::Left)))
{
assert(lowerBoundLayout() != nullptr);
return lowerBoundLayout()->moveDownInside(cursor, shouldRecomputeLayout);
return lowerBoundLayout()->cursorInDescendantsUnder(cursor, shouldRecomputeLayout);
}
return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorUnder(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
int IntegralLayout::writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits) const {

View File

@@ -17,10 +17,10 @@ public:
void deleteBeforeCursor(ExpressionLayoutCursor * cursor) override;
/* Tree navigation */
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
/* Expression Engine */
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override;

View File

@@ -15,24 +15,21 @@ ExpressionLayout * MatrixLayout::clone() const {
return layout;
}
bool MatrixLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor MatrixLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
int childIndex = indexOfChild(cursor->pointedExpressionLayout());
if (childIndex >- 1
&& cursor->position() == ExpressionLayoutCursor::Position::Left
&& childIsLeftOfGrid(childIndex))
{
// Case: Left of a child on the left of the grid.
// Remove the grey squares of the grid, then go left of the grid.
/* Case: Left of a child on the left of the grid.
* 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;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
// Case: Right.
// Add the grey squares to the matrix, then move to the bottom right non empty
// nor grey child.
/* Case: Right. Add the grey squares to the matrix, then move to the bottom
* right non empty nor grey child. */
if (cursor->pointedExpressionLayout() == this
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
@@ -41,15 +38,13 @@ bool MatrixLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomp
*shouldRecomputeLayout = true;
ExpressionLayout * lastChild = editableChild((m_numberOfColumns-1)*(m_numberOfRows-1));
assert(lastChild != nullptr);
cursor->setPointedExpressionLayout(lastChild);
return true;
return ExpressionLayoutCursor(lastChild, ExpressionLayoutCursor::Position::Right);
}
return GridLayout::moveLeft(cursor, shouldRecomputeLayout);
return GridLayout::cursorLeftOf(cursor, shouldRecomputeLayout);
}
bool MatrixLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left.
// Add the grey squares to the matrix,, then go to the first entry.
ExpressionLayoutCursor MatrixLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left. Add the grey squares to the matrix, then go to the first entry.
if (cursor->pointedExpressionLayout() == this
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
@@ -59,8 +54,7 @@ bool MatrixLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecom
assert(m_numberOfColumns*m_numberOfRows >= 1);
ExpressionLayout * firstChild = editableChild(0);
assert(firstChild != nullptr);
cursor->setPointedExpressionLayout(firstChild);
return true;
return ExpressionLayoutCursor(firstChild, ExpressionLayoutCursor::Position::Left);
}
// Case: The cursor points to a grid's child.
int childIndex = indexOfChild(cursor->pointedExpressionLayout());
@@ -68,19 +62,18 @@ bool MatrixLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecom
&& cursor->position() == ExpressionLayoutCursor::Position::Right
&& childIsRightOfGrid(childIndex))
{
// Case: Right of a child on the right of the grid.
// Remove the grey squares of the grid, then go right of the grid.
cursor->setPointedExpressionLayout(this);
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
/* Case: Right of a child on the right of the grid. Remove the grey squares
* of the grid, then go right of the grid. */
assert(hasGreySquares());
removeGreySquares();
*shouldRecomputeLayout = true;
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
return GridLayout::moveRight(cursor, shouldRecomputeLayout);
return GridLayout::cursorRightOf(cursor, shouldRecomputeLayout);
}
bool MatrixLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor MatrixLayout::cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
bool shouldRemoveGreySquares = false;
for (int childIndex = 0; childIndex < m_numberOfColumns; childIndex++) {
if (cursor->pointedExpressionLayout()->hasAncestor(child(childIndex), true)) {
@@ -89,16 +82,16 @@ bool MatrixLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomput
break;
}
}
bool returnValue = GridLayout::moveUp(cursor, shouldRecomputeLayout, equivalentPositionVisited);
if (returnValue && shouldRemoveGreySquares) {
ExpressionLayoutCursor resultCursor = GridLayout::cursorAbove(cursor, shouldRecomputeLayout, equivalentPositionVisited);
if (resultCursor.isDefined() && shouldRemoveGreySquares) {
assert(hasGreySquares());
removeGreySquares();
*shouldRecomputeLayout = true;
}
return returnValue;
return resultCursor;
}
bool MatrixLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor MatrixLayout::cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
bool shouldRemoveGreySquares = false;
for (int childIndex = numberOfChildren() - m_numberOfColumns; childIndex < m_numberOfChildren; childIndex++) {
if (cursor->pointedExpressionLayout()->hasAncestor(child(childIndex), true)) {
@@ -107,18 +100,18 @@ bool MatrixLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomp
break;
}
}
bool returnValue = GridLayout::moveDown(cursor, shouldRecomputeLayout, equivalentPositionVisited);
if (returnValue && shouldRemoveGreySquares) {
ExpressionLayoutCursor resultCursor = GridLayout::cursorUnder(cursor, shouldRecomputeLayout, equivalentPositionVisited);
if (resultCursor.isDefined() && shouldRemoveGreySquares) {
assert(hasGreySquares());
removeGreySquares();
*shouldRecomputeLayout = true;
}
return returnValue;
return resultCursor;
}
bool MatrixLayout::moveUpInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
bool result = GridLayout::moveUpInside(cursor, shouldRecomputeLayout);
if (result && cursor->pointedExpressionLayout() != this) {
ExpressionLayoutCursor MatrixLayout::cursorInDescendantsAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor result = GridLayout::cursorInDescendantsAbove(cursor, shouldRecomputeLayout);
if (result.isDefined() && cursor->pointedExpressionLayout() != this) {
// Add the grey squares if the cursor is pointing at a matrix descendant,
// not at the matrix itself.
assert(!hasGreySquares());
@@ -128,9 +121,9 @@ bool MatrixLayout::moveUpInside(ExpressionLayoutCursor * cursor, bool * shouldRe
return result;
}
bool MatrixLayout::moveDownInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
bool result = GridLayout::moveDownInside(cursor, shouldRecomputeLayout);
if (result && cursor->pointedExpressionLayout() != this) {
ExpressionLayoutCursor MatrixLayout::cursorInDescendantsUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor result = GridLayout::cursorInDescendantsUnder(cursor, shouldRecomputeLayout);
if (result.isDefined() && cursor->pointedExpressionLayout() != this) {
// Add the grey squares if the cursor is pointing at a matrix descendant,
// not at the matrix itself.
assert(!hasGreySquares());

View File

@@ -11,12 +11,12 @@ public:
ExpressionLayout * clone() const override;
/* Navigation */
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
bool moveUpInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveDownInside(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorInDescendantsAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorInDescendantsUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
/* Dynamic layout */
void replaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild) override;

View File

@@ -50,128 +50,102 @@ void NthRootLayout::deleteBeforeCursor(ExpressionLayoutCursor * cursor) {
ExpressionLayout::deleteBeforeCursor(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.
ExpressionLayoutCursor NthRootLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the radicand. Go the index if any, else go Left of the root.
if (radicandLayout()
&& cursor->pointedExpressionLayout() == radicandLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
if (indexLayout()) {
cursor->setPointedExpressionLayout(indexLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(indexLayout(), ExpressionLayoutCursor::Position::Right);
}
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
// Case: Left of the index.
// Go Left of the root.
// Case: Left of the index. Go Left of the root.
if (indexLayout()
&& cursor->pointedExpressionLayout() == indexLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Go Right of the radicand.
// Case: Right. Go Right of the radicand.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
assert(radicandLayout() != nullptr);
cursor->setPointedExpressionLayout(radicandLayout());
return true;
return ExpressionLayoutCursor(radicandLayout(), ExpressionLayoutCursor::Position::Right);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool NthRootLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the radicand.
// Go the Right of the root.
ExpressionLayoutCursor NthRootLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the radicand. Go the Right of the root.
if (radicandLayout()
&& cursor->pointedExpressionLayout() == radicandLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
// Case: Right of the index.
// Go Left of the integrand.
// Case: Right of the index. Go Left of the integrand.
if (indexLayout()
&& cursor->pointedExpressionLayout() == indexLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
assert(radicandLayout() != nullptr);
cursor->setPointedExpressionLayout(radicandLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(radicandLayout(), ExpressionLayoutCursor::Position::Left);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Go index if there is one, else go to the radicand.
// Case: Left. Go index if there is one, else go to the radicand.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
if (indexLayout()) {
cursor->setPointedExpressionLayout(indexLayout());
return true;
return ExpressionLayoutCursor(indexLayout(), ExpressionLayoutCursor::Position::Left);
}
assert(radicandLayout() != nullptr);
cursor->setPointedExpressionLayout(radicandLayout());
return true;
return ExpressionLayoutCursor(radicandLayout(), ExpressionLayoutCursor::Position::Left);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool NthRootLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor NthRootLayout::cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// If the cursor is Left of the radicand, move it to the index.
if (indexLayout()
&& radicandLayout()
&& cursor->isEquivalentTo(ExpressionLayoutCursor(radicandLayout(), ExpressionLayoutCursor::Position::Left)))
{
cursor->setPointedExpressionLayout(indexLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(indexLayout(), ExpressionLayoutCursor::Position::Right);
}
// If the cursor is Left, move it to the index.
if (indexLayout()
&& cursor->pointedExpressionLayout() == this
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
cursor->setPointedExpressionLayout(indexLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(indexLayout(), ExpressionLayoutCursor::Position::Left);
}
return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorAbove(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
bool NthRootLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor NthRootLayout::cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
if (indexLayout() && cursor->pointedExpressionLayout()->hasAncestor(indexLayout(), true)) {
// If the cursor is Right of the index, move it to the radicand.
if (cursor->isEquivalentTo(ExpressionLayoutCursor(indexLayout(), ExpressionLayoutCursor::Position::Right))) {
assert(radicandLayout() != nullptr);
cursor->setPointedExpressionLayout(radicandLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(radicandLayout(), ExpressionLayoutCursor::Position::Left);
}
// If the cursor is Left of the index, move it Left .
if (cursor->isEquivalentTo(ExpressionLayoutCursor(indexLayout(), ExpressionLayoutCursor::Position::Left))) {
cursor->setPointedExpressionLayout(this);
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
}
return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorUnder(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
static_assert('\x90' == Ion::Charset::Root, "Unicode error");

View File

@@ -18,10 +18,10 @@ public:
void deleteBeforeCursor(ExpressionLayoutCursor * cursor) override;
/* Tree navigation */
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
/* Expression Engine */
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override;

View File

@@ -22,38 +22,32 @@ void ParenthesisLayout::invalidAllSizesPositionsAndBaselines() {
ExpressionLayout::invalidAllSizesPositionsAndBaselines();
}
bool ParenthesisLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor ParenthesisLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Go Left.
// Case: Right. Go Left.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool ParenthesisLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
ExpressionLayoutCursor ParenthesisLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Go Right.
// Case: Left. Go Right.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
KDSize ParenthesisLayout::computeSize() {

View File

@@ -9,8 +9,8 @@ class ParenthesisLayout : public StaticLayoutHierarchy<0> {
public:
ParenthesisLayout();
void invalidAllSizesPositionsAndBaselines() override;
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
constexpr static KDCoordinate parenthesisWidth() { return k_widthMargin + k_lineThickness + k_externWidthMargin; }
constexpr static KDCoordinate k_parenthesisCurveWidth = 5;
constexpr static KDCoordinate k_parenthesisCurveHeight = 7;

View File

@@ -17,49 +17,40 @@ void SequenceLayout::deleteBeforeCursor(ExpressionLayoutCursor * cursor) {
ExpressionLayout::deleteBeforeCursor(cursor);
}
bool SequenceLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the bounds.
// Go Left of the sequence.
ExpressionLayoutCursor SequenceLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the bounds. Go Left of the sequence.
if (cursor->position() == ExpressionLayoutCursor::Position::Left
&& ((lowerBoundLayout()
&& cursor->pointedExpressionLayout() == lowerBoundLayout())
|| (upperBoundLayout()
&& cursor->pointedExpressionLayout() == upperBoundLayout())))
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
// Case: Left of the argument.
// Go Right of the lower bound.
// Case: Left of the argument. Go Right of the lower bound.
if (cursor->position() == ExpressionLayoutCursor::Position::Left
&& argumentLayout()
&& cursor->pointedExpressionLayout() == argumentLayout())
{
assert(lowerBoundLayout() != nullptr);
cursor->setPointedExpressionLayout(lowerBoundLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(lowerBoundLayout(), ExpressionLayoutCursor::Position::Right);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Go to the argument and move Left.
// Case: Right. Go to the argument and move Left.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
assert(argumentLayout() != nullptr);
cursor->setPointedExpressionLayout(argumentLayout());
return true;
return ExpressionLayoutCursor(argumentLayout(), ExpressionLayoutCursor::Position::Right);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool SequenceLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the bounds.
// Go Left of the argument.
ExpressionLayoutCursor SequenceLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the bounds. Go Left of the argument.
if (cursor->position() == ExpressionLayoutCursor::Position::Right
&& ((lowerBoundLayout()
&& cursor->pointedExpressionLayout() == lowerBoundLayout())
@@ -67,67 +58,59 @@ bool SequenceLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRec
&& cursor->pointedExpressionLayout() == upperBoundLayout())))
{
assert(argumentLayout() != nullptr);
cursor->setPointedExpressionLayout(argumentLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(argumentLayout(), ExpressionLayoutCursor::Position::Left);
}
// Case: Right of the argument.
// Ask the parent.
// Case: Right of the argument. Go Right.
if (cursor->position() == ExpressionLayoutCursor::Position::Right
&& argumentLayout()
&& cursor->pointedExpressionLayout() == argumentLayout())
{
cursor->setPointedExpressionLayout(this);
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Go to the upper bound.
// Case: Left. Go to the upper bound.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
assert(upperBoundLayout() != nullptr);
cursor->setPointedExpressionLayout(upperBoundLayout());
return true;
return ExpressionLayoutCursor(upperBoundLayout(), ExpressionLayoutCursor::Position::Left);
}
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool SequenceLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor SequenceLayout::cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// If the cursor is inside the lower bound, move it to the upper bound.
if (lowerBoundLayout() && cursor->pointedExpressionLayout()->hasAncestor(lowerBoundLayout(), true)) {
assert(upperBoundLayout() != nullptr);
return upperBoundLayout()->moveUpInside(cursor, shouldRecomputeLayout);
return upperBoundLayout()->cursorInDescendantsAbove(cursor, shouldRecomputeLayout);
}
// If the cursor is Left of the argument, move it to the upper bound.
if (argumentLayout()
&& cursor->isEquivalentTo(ExpressionLayoutCursor(argumentLayout(), ExpressionLayoutCursor::Position::Left)))
{
assert(upperBoundLayout() != nullptr);
return upperBoundLayout()->moveUpInside(cursor, shouldRecomputeLayout);
return upperBoundLayout()->cursorInDescendantsAbove(cursor, shouldRecomputeLayout);
}
return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorAbove(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
bool SequenceLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor SequenceLayout::cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// If the cursor is inside the upper bound, move it to the lower bound.
if (upperBoundLayout() && cursor->pointedExpressionLayout()->hasAncestor(upperBoundLayout(), true)) {
assert(lowerBoundLayout() != nullptr);
return lowerBoundLayout()->moveDownInside(cursor, shouldRecomputeLayout);
return lowerBoundLayout()->cursorInDescendantsUnder(cursor, shouldRecomputeLayout);
}
// If the cursor is Left of the argument, move it to the lower bound.
if (argumentLayout()
&& cursor->isEquivalentTo(ExpressionLayoutCursor(argumentLayout(), ExpressionLayoutCursor::Position::Left)))
{
assert(lowerBoundLayout() != nullptr);
return lowerBoundLayout()->moveDownInside(cursor, shouldRecomputeLayout);
return lowerBoundLayout()->cursorInDescendantsUnder(cursor, shouldRecomputeLayout);
}
return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorUnder(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
ExpressionLayout * SequenceLayout::layoutToPointWhenInserting() {

View File

@@ -11,10 +11,10 @@ public:
constexpr static KDCoordinate k_symbolHeight = 15;
constexpr static KDCoordinate k_symbolWidth = 9;
void deleteBeforeCursor(ExpressionLayoutCursor * cursor) override;
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayout * layoutToPointWhenInserting() override;
char XNTChar() const override;
protected:

View File

@@ -63,128 +63,101 @@ void VerticalOffsetLayout::deleteBeforeCursor(ExpressionLayoutCursor * cursor) {
ExpressionLayout::deleteBeforeCursor(cursor);
}
bool VerticalOffsetLayout::moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the indice.
// Go Left.
ExpressionLayoutCursor VerticalOffsetLayout::cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Left of the indice. Go Left.
if (indiceLayout()
&& cursor->pointedExpressionLayout() == indiceLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Left)
{
cursor->setPointedExpressionLayout(this);
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Right.
// Go to the indice.
// Case: Right. Go to the indice.
if (cursor->position() == ExpressionLayoutCursor::Position::Right) {
assert(indiceLayout() != nullptr);
cursor->setPointedExpressionLayout(indiceLayout());
return true;
return ExpressionLayoutCursor(indiceLayout(), ExpressionLayoutCursor::Position::Right);
}
// Case: Left.
// Ask the parent.
// Case: Left. Ask the parent.
assert(cursor->position() == ExpressionLayoutCursor::Position::Left);
if (m_parent) {
return m_parent->moveLeft(cursor, shouldRecomputeLayout);
return m_parent->cursorLeftOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool VerticalOffsetLayout::moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the indice.
// Go Right.
ExpressionLayoutCursor VerticalOffsetLayout::cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) {
// Case: Right of the indice. Go Right.
if (indiceLayout()
&& cursor->pointedExpressionLayout() == indiceLayout()
&& cursor->position() == ExpressionLayoutCursor::Position::Right)
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right);
}
assert(cursor->pointedExpressionLayout() == this);
// Case: Left.
// Go to the indice.
// Case: Left. Go to the indice.
if (cursor->position() == ExpressionLayoutCursor::Position::Left) {
assert(indiceLayout() != nullptr);
cursor->setPointedExpressionLayout(indiceLayout());
return true;
return ExpressionLayoutCursor(indiceLayout(), ExpressionLayoutCursor::Position::Left);
}
// Case: Right.
// Ask the parent.
// Case: Right. Ask the parent.
assert(cursor->position() == ExpressionLayoutCursor::Position::Right);
if (m_parent) {
return m_parent->moveRight(cursor, shouldRecomputeLayout);
return m_parent->cursorRightOf(cursor, shouldRecomputeLayout);
}
return false;
return ExpressionLayoutCursor();
}
bool VerticalOffsetLayout::moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor VerticalOffsetLayout::cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// Case: Superscript.
if (m_type == VerticalOffsetLayout::Type::Superscript) {
// Case: Right.
// Move to the indice.
// Case: Right. Move to the indice.
if (cursor->isEquivalentTo(ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right))) {
assert(indiceLayout() != nullptr);
cursor->setPointedExpressionLayout(indiceLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(indiceLayout(), ExpressionLayoutCursor::Position::Right);
}
// Case: Left.
// Move to the indice.
// Case: Left. Move to the indice.
if (cursor->isEquivalentTo(ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left))) {
assert(indiceLayout() != nullptr);
cursor->setPointedExpressionLayout(indiceLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(indiceLayout(), ExpressionLayoutCursor::Position::Left);
}
}
// Case: Subscript.
// Case: Left or Right of the indice.
// Put the cursor at the same position, pointing this.
/* Case: Subscript, Left or Right of the indice. Put the cursor at the same
* position, pointing this. */
if (m_type == VerticalOffsetLayout::Type::Subscript
&& indiceLayout() != nullptr
&& (cursor->isEquivalentTo(ExpressionLayoutCursor(indiceLayout(), ExpressionLayoutCursor::Position::Left))
|| cursor->isEquivalentTo(ExpressionLayoutCursor(indiceLayout(), ExpressionLayoutCursor::Position::Right))))
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, cursor->position());
}
return ExpressionLayout::moveUp(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorAbove(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
bool VerticalOffsetLayout::moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
ExpressionLayoutCursor VerticalOffsetLayout::cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited) {
// Case: Subscript.
if (m_type == VerticalOffsetLayout::Type::Subscript) {
// Case: Right.
// Move to the indice.
// Case: Right. Move to the indice.
if (cursor->isEquivalentTo(ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Right))) {
assert(indiceLayout() != nullptr);
cursor->setPointedExpressionLayout(indiceLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Right);
return true;
return ExpressionLayoutCursor(indiceLayout(), ExpressionLayoutCursor::Position::Right);
}
// Case: Left.
// Move to the indice.
// Case: Left. Move to the indice.
if (cursor->isEquivalentTo(ExpressionLayoutCursor(this, ExpressionLayoutCursor::Position::Left))) {
assert(indiceLayout() != nullptr);
cursor->setPointedExpressionLayout(indiceLayout());
cursor->setPosition(ExpressionLayoutCursor::Position::Left);
return true;
return ExpressionLayoutCursor(indiceLayout(), ExpressionLayoutCursor::Position::Left);
}
}
// Case: Superscript.
// Case: Left or Right of the indice.
// Put the cursor at the same position, pointing this.
/* Case: Superscript, Left or Right of the indice. Put the cursor at the same
* position, pointing this. */
if (m_type == VerticalOffsetLayout::Type::Superscript
&& indiceLayout() != nullptr
&& cursor->pointedExpressionLayout() == indiceLayout())
{
cursor->setPointedExpressionLayout(this);
return true;
return ExpressionLayoutCursor(this, cursor->position());
}
return ExpressionLayout::moveDown(cursor, shouldRecomputeLayout, equivalentPositionVisited);
return ExpressionLayout::cursorUnder(cursor, shouldRecomputeLayout, equivalentPositionVisited);
}
int VerticalOffsetLayout::writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits) const {

View File

@@ -15,10 +15,10 @@ public:
Type type() const { return m_type; }
ExpressionLayout * clone() const override;
void deleteBeforeCursor(ExpressionLayoutCursor * cursor) override;
bool moveLeft(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveRight(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
bool moveUp(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
bool moveDown(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorLeftOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorRightOf(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout) override;
ExpressionLayoutCursor cursorAbove(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
ExpressionLayoutCursor cursorUnder(ExpressionLayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) override;
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override;
bool mustHaveLeftSibling() const override { return true; }
bool isVerticalOffset() const { return true; }