mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-24 00:00:44 +01:00
[poincare] Cleaned ExpressionLayout class.
Change-Id: I03a49e1a2b199a70608792f0358ddde5a86118d6
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user