[poincare] LayoutNode::equivalentCursor

This commit is contained in:
Léa Saviot
2018-07-05 14:56:01 +02:00
parent 8a3be2bac3
commit 279e04bdd9
6 changed files with 57 additions and 5 deletions

View File

@@ -3,6 +3,7 @@
#include "layout_node.h"
#include "layout_reference.h"
#include "layout_cursor.h"
namespace Poincare {
@@ -13,6 +14,10 @@ public:
assert(false);
return 0;
}
LayoutCursor equivalentCursor(LayoutCursor * cursor) override { return LayoutCursor(); }
void removeChildAndMoveCursor(LayoutNode * l, LayoutCursor * cursor) override { }
void deleteBeforeCursor(LayoutCursor * cursor) override { }
// TreeNode
size_t size() const override { return sizeof(AllocationFailedLayoutNode); }
const char * description() const override { return "Allocation Failed"; }

View File

@@ -17,6 +17,9 @@ public:
m_numberOfChildren(0)
{}
// Tree navigation
LayoutCursor equivalentCursor(LayoutCursor * cursor) override;
// Tree modification
void addOrMergeChildAtIndex(LayoutNode * l, int index, bool removeEmptyChildren);
void mergeChildrenAtIndex(HorizontalLayoutNode * horizontalLayout, int index, bool removeEmptyChildren);

View File

@@ -7,9 +7,12 @@
namespace Poincare {
class HorizontalLayoutNode;
class LayoutCursor {
template <typename T>
friend class LayoutReference;
friend class HorizontalLayoutNode;
public:
constexpr static KDCoordinate k_cursorWidth = 1;
@@ -52,6 +55,8 @@ public:
/* Getters and setters */
LayoutRef layoutReference() { return m_layoutRef; }
LayoutNode * layoutNode() { return m_layoutRef.typedNode(); } // TODO Make private + friend classes ?
int layoutIdentifier() { return m_layoutRef.identifier(); }
void setLayoutReference(LayoutRef r) {
if (r != m_layoutRef) {

View File

@@ -23,9 +23,9 @@ public:
}
bool hasText() const {
/* A layout has text if it is not empty and it is not an horizontal layout
* with no child or with one child with no text. */
if (isEmpty()){
/* A layout has text if it is not empty or an allocation failure and it is
* not an horizontal layout with no child or with one child with no text. */
if (isEmpty() || isAllocationFailure()){
return false;
}
int numChildren = numberOfChildren();
@@ -66,7 +66,7 @@ public:
virtual void moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) {}
virtual void moveCursorUp(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) {}
virtual void moveCursorDown(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) {}
virtual LayoutCursor equivalentCursor(LayoutCursor * cursor); //TODO
virtual LayoutCursor equivalentCursor(LayoutCursor * cursor);
// Tree modification
void addSibling(LayoutCursor * cursor, LayoutNode * sibling);

View File

@@ -5,6 +5,39 @@ namespace Poincare {
static inline KDCoordinate maxCoordinate(KDCoordinate c1, KDCoordinate c2) { return c1 > c2 ? c1 : c2; }
// Tree navigation
LayoutCursor HorizontalLayoutNode::equivalentCursor(LayoutCursor * cursor) {
if (cursor->layoutReference().node() == this) {
// First or last child, if any
int childrenCount = numberOfChildren();
if (childrenCount == 0) {
return LayoutCursor();
}
int index = cursor->position() == LayoutCursor::Position::Left ? 0 : childrenCount - 1;
return LayoutCursor(childAtIndex(index), cursor->position());
}
// Left or right of a child: return right or left of its sibling, or of this
int indexOfPointedLayout = indexOfChild(cursor->layoutNode());
if (indexOfPointedLayout < 0) {
return LayoutCursor();
}
if (cursor->position() == LayoutCursor::Position::Left) {
if (indexOfPointedLayout == 0) {
return LayoutCursor(this, LayoutCursor::Position::Left);
}
return LayoutCursor(childAtIndex(indexOfPointedLayout - 1), LayoutCursor::Position::Right);
}
assert(cursor->position() == LayoutCursor::Position::Right);
if (indexOfPointedLayout == numberOfChildren() - 1) {
return LayoutCursor(this, LayoutCursor::Position::Right);
}
return LayoutCursor(childAtIndex(indexOfPointedLayout + 1), LayoutCursor::Position::Left);
}
// Tree modification
void HorizontalLayoutNode::addOrMergeChildAtIndex(LayoutNode * l, int index, bool removeEmptyChildren) {
if (l->isHorizontal()) {
mergeChildrenAtIndex(static_cast<HorizontalLayoutNode *>(l), index, removeEmptyChildren);
@@ -79,6 +112,8 @@ void HorizontalLayoutNode::removeChildAndMoveCursor(LayoutNode * l, LayoutCursor
LayoutNode::removeChildAndMoveCursor(l, cursor);
}
// LayoutNode
int HorizontalLayoutNode::writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits) const {
if (numberOfChildren() == 0) {
if (bufferSize == 0) {
@@ -180,6 +215,8 @@ void HorizontalLayoutNode::moveCursorRight(LayoutCursor * cursor, bool * shouldR
return childAtIndex(childIndex+1)->moveCursorRight(cursor, shouldRecomputeLayout);
}
// Protected
void HorizontalLayoutNode::computeSize() {
assert(!m_sized);
KDCoordinate totalWidth = 0;

View File

@@ -69,7 +69,9 @@ TreeNode * LayoutNode::FailedAllocationStaticNode() {
// Tree navigation
LayoutCursor LayoutNode::equivalentCursor(LayoutCursor * cursor) {
return LayoutCursor(cursor->layoutReference());
// Only HorizontalLayout may have no parent, and it overloads this method
assert(parent());
return (cursor->layoutReference().node() == this) ? parent()->equivalentCursor(cursor) : LayoutCursor();
}
// Tree modification