[poincare] Cleaned ExpressionLayout class.

Change-Id: I03a49e1a2b199a70608792f0358ddde5a86118d6
This commit is contained in:
Léa Saviot
2018-01-11 11:08:58 +01:00
parent 95327d0afc
commit f95bb46cc3
4 changed files with 92 additions and 76 deletions

View File

@@ -32,38 +32,60 @@ public:
virtual void invalidAllSizesPositionsAndBaselines();
/* Hierarchy */
// Children
virtual const ExpressionLayout * const * children() const = 0;
const ExpressionLayout * child(int i) const;
ExpressionLayout * editableChild(int i) { return const_cast<ExpressionLayout *>(child(i)); }
virtual int numberOfChildren() const = 0;
int indexOfChild(ExpressionLayout * child) const;
int indexOfChild(const ExpressionLayout * child) const;
void setParent(ExpressionLayout * parent);
// Parent
void setParent(ExpressionLayout * parent) { m_parent = parent; }
const ExpressionLayout * parent() const { return m_parent; }
ExpressionLayout * editableParent() { return m_parent; }
bool hasAncestor(const ExpressionLayout * e) const;
/* Dynamic Layout */
bool insertLayoutAtCursor(ExpressionLayout * newChild, ExpressionLayoutCursor * cursor);
// Add
virtual bool addChildAtIndex(ExpressionLayout * child, int index) { return false; }
virtual void addBrother(ExpressionLayoutCursor * cursor, ExpressionLayout * brother);
// Replace
virtual ExpressionLayout * replaceWith(ExpressionLayout * newChild, bool deleteAfterReplace = true);
ExpressionLayout * replaceWithJuxtapositionOf(ExpressionLayout * leftChild, ExpressionLayout * rightChild, bool deleteAfterReplace);
ExpressionLayout * replaceWithAndMoveCursor(ExpressionLayout * newChild, bool deleteAfterReplace, ExpressionLayoutCursor * cursor);
virtual void replaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild = true);
virtual void replaceChildAndMoveCursor(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor);
void detachChild(const ExpressionLayout * e); // Removes a child WITHOUT deleting it
void detachChildren(); //Removes all children WITHOUT deleting them
virtual bool addChildAtIndex(ExpressionLayout * child, int index) { return false; }
virtual void replaceChildAndMoveCursor(
const ExpressionLayout * oldChild,
ExpressionLayout * newChild,
bool deleteOldChild,
ExpressionLayoutCursor * cursor);
// Detach
void detachChild(const ExpressionLayout * e); // Detach a child WITHOUT deleting it
void detachChildren(); // Detach all children WITHOUT deleting them
// Remove
virtual void removeChildAtIndex(int index, bool deleteAfterRemoval);
virtual void removePointedChildAtIndexAndMoveCursor(int index, bool deleteAfterRemoval, ExpressionLayoutCursor * cursor);
// User input
bool insertLayoutAtCursor(ExpressionLayout * newChild, ExpressionLayoutCursor * cursor);
virtual void backspaceAtCursor(ExpressionLayoutCursor * cursor);
/* Tree navigation */
virtual bool moveLeft(ExpressionLayoutCursor * cursor) { return false; } //TODO should be virtual pure?
virtual bool moveRight(ExpressionLayoutCursor * cursor) { return false; } //TODO should be virtual pure?
virtual bool moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout = nullptr, ExpressionLayout * previousPreviousLayout = nullptr);
virtual bool moveUp(
ExpressionLayoutCursor * cursor,
ExpressionLayout * previousLayout = nullptr,
ExpressionLayout * previousPreviousLayout = nullptr);
virtual bool moveDown(
ExpressionLayoutCursor * cursor,
ExpressionLayout * previousLayout = nullptr,
ExpressionLayout * previousPreviousLayout = nullptr);
bool moveUpInside(ExpressionLayoutCursor * cursor);
virtual bool moveDown(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout = nullptr, ExpressionLayout * previousPreviousLayout = nullptr);
bool moveDownInside(ExpressionLayoutCursor * cursor);
/* Expression Engine */
@@ -71,7 +93,8 @@ public:
/* Other */
virtual bool isCollapsable(int * numberOfOpenParenthesis, bool goingLeft) const { return true; }
// isCollapsable is used when adding a brother fraction: should the layout be inserted in the numerator (or denominator)?
/* isCollapsable is used when adding a brother fraction: should the layout be
* inserted in the numerator (or denominator)? */
virtual bool mustHaveLeftBrother() const { return false; }
virtual bool isHorizontal() const { return false; }
virtual bool isLeftParenthesis() const { return false; }
@@ -87,24 +110,24 @@ protected:
virtual KDSize computeSize() = 0;
virtual void computeBaseline() = 0;
virtual KDPoint positionOfChild(ExpressionLayout * child) = 0;
ExpressionLayout * m_parent;
KDCoordinate m_baseline;
/* m_baseline is the signed vertical distance from the top of the layout to
* the fraction bar of an hypothetical fraction brother layout. If the top of
* the layout is under that bar, the baseline is negative. */
bool m_sized;
bool m_baselined;
bool m_positioned;
private:
void detachChildAtIndex(int i);
bool moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor);
void moveCursorInsideAtDirection (
VerticalDirection direction,
ExpressionLayoutCursor * cursor,
ExpressionLayout ** childResult,
void * resultPosition,
int * resultScore);
KDCoordinate m_baseline;
/* m_baseline is the signed vertical distance from the top of the layout to
* the fraction bar of an hypothetical fraction brother layout. If the top of
* the layout is under that bar, the baseline is negative. */
ExpressionLayout * m_parent;
bool m_sized;
bool m_baselined;
bool m_positioned;
private:
bool moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor);
void replaceWithJuxtapositionOf(ExpressionLayout * firstLayout, ExpressionLayout * secondLayout);
ExpressionLayout * replaceWithJuxtapositionOf(ExpressionLayout * leftChild, ExpressionLayout * rightChild, bool deleteAfterReplace);
KDRect m_frame;
};

View File

@@ -10,8 +10,8 @@
namespace Poincare {
ExpressionLayout::ExpressionLayout() :
m_baseline(0),
m_parent(nullptr),
m_baseline(0),
m_sized(false),
m_baselined(false),
m_positioned(false),
@@ -19,6 +19,14 @@ ExpressionLayout::ExpressionLayout() :
{
}
void ExpressionLayout::draw(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
int i = 0;
while (ExpressionLayout * c = editableChild(i++)) {
c->draw(ctx, p, expressionColor, backgroundColor);
}
render(ctx, absoluteOrigin().translatedBy(p), expressionColor, backgroundColor);
}
KDPoint ExpressionLayout::origin() {
if (m_parent == nullptr) {
return absoluteOrigin();
@@ -28,14 +36,6 @@ KDPoint ExpressionLayout::origin() {
}
}
void ExpressionLayout::draw(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
int i = 0;
while (ExpressionLayout * c = editableChild(i++)) {
c->draw(ctx, p, expressionColor, backgroundColor);
}
render(ctx, absoluteOrigin().translatedBy(p), expressionColor, backgroundColor);
}
KDPoint ExpressionLayout::absoluteOrigin() {
if (!m_positioned) {
if (m_parent != nullptr) {
@@ -83,7 +83,7 @@ const ExpressionLayout * ExpressionLayout::child(int i) const {
return nullptr;
}
int ExpressionLayout::indexOfChild(ExpressionLayout * child) const {
int ExpressionLayout::indexOfChild(const ExpressionLayout * child) const {
if (child == nullptr) {
return -1;
}
@@ -95,10 +95,6 @@ int ExpressionLayout::indexOfChild(ExpressionLayout * child) const {
return -1;
}
void ExpressionLayout::setParent(ExpressionLayout* parent) {
m_parent = parent;
}
bool ExpressionLayout::hasAncestor(const ExpressionLayout * e) const {
assert(m_parent != this);
if (m_parent == e) {
@@ -143,28 +139,12 @@ void ExpressionLayout::addBrother(ExpressionLayoutCursor * cursor, ExpressionLay
return;
}
bool ExpressionLayout::insertLayoutAtCursor(ExpressionLayout * newChild, ExpressionLayoutCursor * cursor) {
cursor->pointedExpressionLayout()->addBrother(cursor, newChild);
return true;
}
ExpressionLayout * ExpressionLayout::replaceWith(ExpressionLayout * newChild, bool deleteAfterReplace) {
assert(m_parent != nullptr);
m_parent->replaceChild(this, newChild, deleteAfterReplace);
return newChild;
}
ExpressionLayout * ExpressionLayout::replaceWithJuxtapositionOf(ExpressionLayout * leftChild, ExpressionLayout * rightChild, bool deleteAfterReplace) {
assert(m_parent != nullptr);
/* One of the children to juxtapose might be "this", so we first have to
* replace "this" with an horizontal layout, then add "this" to the layout. */
ExpressionLayout * layout = new HorizontalLayout();
m_parent->replaceChild(this, layout, deleteAfterReplace);
layout->addChildAtIndex(leftChild, 0);
layout->addChildAtIndex(rightChild, 1);
return layout;
}
ExpressionLayout * ExpressionLayout::replaceWithAndMoveCursor(ExpressionLayout * newChild, bool deleteAfterReplace, ExpressionLayoutCursor * cursor) {
assert(m_parent != nullptr);
m_parent->replaceChildAndMoveCursor(this, newChild, deleteAfterReplace, cursor);
@@ -199,7 +179,7 @@ void ExpressionLayout::replaceChild(const ExpressionLayout * oldChild, Expressio
}
void ExpressionLayout::replaceChildAndMoveCursor(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor) {
int oldChildIndex = indexOfChild(const_cast<ExpressionLayout *>(oldChild));
int oldChildIndex = indexOfChild(oldChild);
assert(oldChildIndex >= 0);
if (oldChildIndex == 0) {
cursor->setPointedExpressionLayout(this);
@@ -212,16 +192,12 @@ void ExpressionLayout::replaceChildAndMoveCursor(const ExpressionLayout * oldChi
}
void ExpressionLayout::detachChild(const ExpressionLayout * e) {
ExpressionLayout ** op = const_cast<ExpressionLayout **>(children());
for (int i = 0; i < numberOfChildren(); i++) {
if (op[i] == e) {
detachChildAtIndex(i);
}
}
assert(indexOfChild(e) >= 0);
detachChildAtIndex(indexOfChild(e));
}
void ExpressionLayout::detachChildren() {
for (int i = 0; i <numberOfChildren(); i++) {
for (int i = 0; i < numberOfChildren(); i++) {
detachChildAtIndex(i);
}
}
@@ -246,6 +222,12 @@ void ExpressionLayout::removePointedChildAtIndexAndMoveCursor(int index, bool de
cursor->setPointedExpressionLayout(editableChild(indexOfNewPointedLayout));
}
bool ExpressionLayout::insertLayoutAtCursor(ExpressionLayout * newChild, ExpressionLayoutCursor * cursor) {
cursor->pointedExpressionLayout()->addBrother(cursor, newChild);
return true;
}
void ExpressionLayout::backspaceAtCursor(ExpressionLayoutCursor * cursor) {
int indexOfPointedExpression = indexOfChild(cursor->pointedExpressionLayout());
if (indexOfPointedExpression >= 0) {
@@ -302,17 +284,6 @@ char ExpressionLayout::XNTChar() const {
return m_parent->XNTChar();
}
void ExpressionLayout::detachChildAtIndex(int i) {
ExpressionLayout ** op = const_cast<ExpressionLayout **>(children());
if (op[i] != nullptr && op[i]->parent() == this) {
const_cast<ExpressionLayout *>(op[i])->setParent(nullptr);
}
op[i] = nullptr;
m_sized = false;
m_positioned = false;
m_baselined = false;
}
bool ExpressionLayout::moveUp(ExpressionLayoutCursor * cursor, ExpressionLayout * previousLayout, ExpressionLayout * previousPreviousLayout) {
if (m_parent) {
return m_parent->moveUp(cursor, this, previousLayout);
@@ -335,6 +306,17 @@ bool ExpressionLayout::moveDownInside(ExpressionLayoutCursor * cursor) {
return moveInside(VerticalDirection::Down, cursor);
}
void ExpressionLayout::detachChildAtIndex(int i) {
ExpressionLayout ** op = const_cast<ExpressionLayout **>(children());
if (op[i] != nullptr && op[i]->parent() == this) {
const_cast<ExpressionLayout *>(op[i])->setParent(nullptr);
}
op[i] = nullptr;
m_sized = false;
m_positioned = false;
m_baselined = false;
}
bool ExpressionLayout::moveInside(VerticalDirection direction, ExpressionLayoutCursor * cursor) {
ExpressionLayout * chilResult = nullptr;
ExpressionLayout ** childResultPtr = &chilResult;
@@ -391,4 +373,15 @@ void ExpressionLayout::moveCursorInsideAtDirection (
}
}
ExpressionLayout * ExpressionLayout::replaceWithJuxtapositionOf(ExpressionLayout * leftChild, ExpressionLayout * rightChild, bool deleteAfterReplace) {
assert(m_parent != nullptr);
/* One of the children to juxtapose might be "this", so we first have to
* replace "this" with an horizontal layout, then add "this" to the layout. */
ExpressionLayout * layout = new HorizontalLayout();
m_parent->replaceChild(this, layout, deleteAfterReplace);
layout->addChildAtIndex(leftChild, 0);
layout->addChildAtIndex(rightChild, 1);
return layout;
}
}

View File

@@ -38,7 +38,7 @@ void HorizontalLayout::privateReplaceChild(const ExpressionLayout * oldChild, Ex
if (newChild->hasAncestor(this)) {
newChild->editableParent()->detachChild(newChild);
}
int oldChildIndex = indexOfChild(const_cast<ExpressionLayout *>(oldChild));
int oldChildIndex = indexOfChild(oldChild);
if (newChild->isEmpty()) {
if (numberOfChildren() > 1) {
// If the new layout is empty and the horizontal layout has other
@@ -46,7 +46,7 @@ void HorizontalLayout::privateReplaceChild(const ExpressionLayout * oldChild, Ex
if (!newChild->hasAncestor(oldChild)) {
delete newChild;
}
removeChildAtIndex(indexOfChild(const_cast<ExpressionLayout *>(oldChild)), deleteOldChild);
removeChildAtIndex(oldChildIndex, deleteOldChild);
if (cursor == nullptr) {
return;
}
@@ -74,7 +74,7 @@ void HorizontalLayout::privateReplaceChild(const ExpressionLayout * oldChild, Ex
// If the new child is also an horizontal layout, steal the children of the
// new layout then destroy it.
if (newChild->isHorizontal()) {
int indexForInsertion = indexOfChild(const_cast<ExpressionLayout *>(oldChild));
int indexForInsertion = indexOfChild(oldChild);
mergeChildrenAtIndex(static_cast<HorizontalLayout *>(newChild), indexForInsertion + 1, true);
removeChildAtIndex(indexForInsertion, deleteOldChild);
if (cursor == nullptr) {

View File

@@ -18,13 +18,13 @@ ExpressionLayout * MatrixLayout::clone() const {
}
void MatrixLayout::replaceChild(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild) {
int oldChildIndex = indexOfChild(const_cast<ExpressionLayout *>(oldChild));
int oldChildIndex = indexOfChild(oldChild);
GridLayout::replaceChild(oldChild, newChild, deleteOldChild);
childWasReplacedAtIndex(oldChildIndex);
}
void MatrixLayout::replaceChildAndMoveCursor(const ExpressionLayout * oldChild, ExpressionLayout * newChild, bool deleteOldChild, ExpressionLayoutCursor * cursor) {
int oldChildIndex = indexOfChild(const_cast<ExpressionLayout *>(oldChild));
int oldChildIndex = indexOfChild(oldChild);
int rowIndex = rowAtChildIndex(oldChildIndex);
int columnIndex = columnAtChildIndex(oldChildIndex);
replaceChild(oldChild, newChild, deleteOldChild);