From 9a7441d0451660be716d4b4dd2ad9ac4dc46c9f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9a=20Saviot?= Date: Tue, 26 Jun 2018 15:56:03 +0200 Subject: [PATCH] Define a cursor on layout children --- horizontal_layout_node.h | 95 ++++++++++++++++++++++++++++++++++++++++ layout_reference.cpp | 2 + layout_reference.h | 3 +- test.cpp | 13 ++++-- tree_reference.h | 14 +++--- 5 files changed, 118 insertions(+), 9 deletions(-) create mode 100644 horizontal_layout_node.h diff --git a/horizontal_layout_node.h b/horizontal_layout_node.h new file mode 100644 index 000000000..d1643cf44 --- /dev/null +++ b/horizontal_layout_node.h @@ -0,0 +1,95 @@ +#ifndef HORIZONTAL_LAYOUT_H +#define HORIZONTAL_LAYOUT_H + +#include "layout_reference.h" +#include "layout_node.h" +#include "layout_cursor.h" + +class HorizontalLayoutNode : public LayoutNode { +public: + HorizontalLayoutNode() : + LayoutNode(), + m_numberOfChildren(0) + {} + + size_t size() const override { + return sizeof(HorizontalLayoutNode); + } + + int numberOfChildren() const override { return m_numberOfChildren; } + void incrementNumberOfChildren() { m_numberOfChildren++; } + + void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) override { + if (this == cursor->layoutReference().node()) { + if (cursor->position() == LayoutCursor::Position::Left) { + // Case: Left. Ask the parent. + LayoutNode * parentNode = parent(); + if (parentNode != nullptr) { + parentNode->moveCursorLeft(cursor, shouldRecomputeLayout); + } + return; + } + assert(cursor->position() == LayoutCursor::Position::Right); + /* Case: Right. Go to the last child if there is one, and move Left. Else + * go Left and ask the parent. */ + int childrenCount = numberOfChildren(); + if (childrenCount >= 1) { + cursor->setLayoutNode(static_cast(childTreeAtIndex(childrenCount-1))); + } else { + cursor->setPosition(LayoutCursor::Position::Left); + } + return cursor->moveLeft(shouldRecomputeLayout); + } + + // Case: The cursor is Left of a child. + assert(cursor->position() == LayoutCursor::Position::Left); + int childIndex = indexOfChildByIdentifier(cursor->layoutIdentifier()); + assert(childIndex >= 0); + if (childIndex == 0) { + // Case: the child is the leftmost. Ask the parent. + if (parent()) { + cursor->setLayoutNode(this); + return cursor->moveLeft(shouldRecomputeLayout); + } + return; + } + // Case: the child is not the leftmost. Go to its left sibling and move Left. + cursor->setLayoutNode(static_cast(childTreeAtIndex(childIndex-1))); + cursor->setPosition(LayoutCursor::Position::Right); + cursor->moveLeft(shouldRecomputeLayout); + } + + void moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) override { + //TODO + LayoutNode * parentNode = parent(); + if (parentNode != nullptr) { + parentNode->moveCursorRight(cursor, shouldRecomputeLayout); + } + } + + const char * description() const override { + return "Horizontal Layout"; + } +private: + int m_numberOfChildren; +}; + +class HorizontalLayoutRef : public LayoutReference { +public: + HorizontalLayoutRef() : LayoutReference() {} + HorizontalLayoutRef(LayoutRef l) : LayoutReference() { + addChild(l); + } + + HorizontalLayoutRef(LayoutRef l1, LayoutRef l2) : LayoutReference() { + addChild(l2); + addChild(l1); + } + + virtual void addChild(LayoutRef l) override { + LayoutReference::addChild(l); + node()->incrementNumberOfChildren(); + } +}; + +#endif diff --git a/layout_reference.cpp b/layout_reference.cpp index abfb824d5..52ffecc96 100644 --- a/layout_reference.cpp +++ b/layout_reference.cpp @@ -1,5 +1,6 @@ #include "layout_reference.h" #include "layout_cursor.h" +#include "layout_node.h" #include "char_layout_node.h" template @@ -7,4 +8,5 @@ LayoutCursor LayoutReference::cursor() const { return LayoutCursor(this->node()); } +template LayoutCursor LayoutReference::cursor() const; template LayoutCursor LayoutReference::cursor() const; diff --git a/layout_reference.h b/layout_reference.h index c98dda91f..b9659ab8f 100644 --- a/layout_reference.h +++ b/layout_reference.h @@ -30,7 +30,8 @@ public: } LayoutReference childAtIndex(int i) { - return TreeReference::childAtIndex(i); + TreeReference treeRefChild = TreeReference::treeChildAtIndex(i); + return LayoutReference(treeRefChild.node()); } void replaceChildAtIndex(int oldChildIndex, LayoutReference newChild) { diff --git a/test.cpp b/test.cpp index 96a79bb7a..00da8a0ef 100644 --- a/test.cpp +++ b/test.cpp @@ -1,5 +1,6 @@ #include "float_node.h" #include "char_layout_node.h" +#include "horizontal_layout_node.h" #include "addition_node.h" #include "cursor.h" #include @@ -22,11 +23,17 @@ int main() { TreePool::sharedPool()->log();*/ printf("\nCHAR LAYOUT\n"); - CharLayout aChar('a'); + CharLayout aChar('c'); + CharLayout bChar('b'); TreePool::sharedPool()->log(); - Cursor cursor = aChar.cursor(); -/* TreePool::sharedPool()->log(); + + HorizontalLayout h(aChar, bChar); + TreePool::sharedPool()->log(); + + LayoutCursor cursor = h.childAtIndex(1).cursor(); cursor.log(); + + /*cursor.log(); bool recompute = false; cursor.moveLeft(&recompute); cursor.log(); diff --git a/tree_reference.h b/tree_reference.h index 6301c00bd..d99894089 100644 --- a/tree_reference.h +++ b/tree_reference.h @@ -12,6 +12,10 @@ class Cursor; template class TreeReference { friend class Cursor; + template + friend class ExpressionReference; + template + friend class LayoutReference; public: TreeReference(const TreeReference & tr) { int trNodeIdentifier = tr.identifier(); @@ -52,8 +56,8 @@ public: return TreeReference(node()->parentTree()); } - TreeReference childAtIndex(int i) const { - return TreeReference(node()->child(i)); + TreeReference treeChildAtIndex(int i) const { + return TreeReference(node()->childTreeAtIndex(i)); } // Hierarchy operations @@ -74,7 +78,7 @@ public: void replaceChildAtIndex(int oldChildIndex, TreeReference newChild) { assert(oldChildIndex >= 0 && oldChildIndex < numberOfChildren()); - TreeReference oldChild = childAtIndex(oldChildIndex); + TreeReference oldChild = treeChildAtIndex(oldChildIndex); TreePool::sharedPool()->move(newChild.node(), oldChild.node()->next()); newChild.node()->retain(); TreePool::sharedPool()->move(oldChild.node(), TreePool::sharedPool()->last()); @@ -89,8 +93,8 @@ public: } int firstChildIndex = min(i, j); int secondChildIndex = max(i, j); - TreeReference firstChild = childAtIndex(firstChildIndex); - TreeReference secondChild = childAtIndex(secondChildIndex); + TreeReference firstChild = treeChildAtIndex(firstChildIndex); + TreeReference secondChild = treeChildAtIndex(secondChildIndex); TreeNode * firstChildNode = firstChild.node(); TreePool::sharedPool()->move(firstChildNode, secondChild.node()->next()); TreePool::sharedPool()->move(secondChild.node(), firstChildNode);