mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-28 18:20:14 +01:00
[poincare] moveLeft renamed cursorOnLeft, same for other directions
Change-Id: Ic46604ea81eabdb2e10755a67307169d90654efd
This commit is contained in:
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user