mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
[poincare] Adapt CharLayoutNode and HorizontalLayoutNode
This commit is contained in:
@@ -3,6 +3,14 @@ SFLAGS += -Ipoincare/include
|
||||
#include poincare/src/simplify/Makefile
|
||||
#include poincare/src/simplification/Makefile
|
||||
|
||||
objs += $(addprefix poincare/src/,\
|
||||
char_layout_node.o\
|
||||
horizontal_layout_node.o\
|
||||
layout_cursor.o\
|
||||
layout_node.o\
|
||||
layout_reference.o\
|
||||
)
|
||||
|
||||
objs += $(addprefix poincare/src/,\
|
||||
absolute_value.o\
|
||||
addition.o\
|
||||
@@ -47,10 +55,7 @@ objs += $(addprefix poincare/src/,\
|
||||
imaginary_part.o\
|
||||
integer.o\
|
||||
integral.o\
|
||||
layout_cursor.o\
|
||||
layout_engine.o\
|
||||
layout_node.o\
|
||||
layout_reference.o\
|
||||
list_data.o\
|
||||
least_common_multiple.o\
|
||||
logarithm.o\
|
||||
|
||||
@@ -8,11 +8,28 @@ namespace Poincare {
|
||||
|
||||
class AllocationFailedLayoutNode : public LayoutNode {
|
||||
public:
|
||||
// LayoutNode
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override {
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(AllocationFailedLayoutNode); }
|
||||
const char * description() const override { return "Allocation Failed"; }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
bool isAllocationFailure() const override { return true; }
|
||||
|
||||
protected:
|
||||
// LayoutNode
|
||||
void computeSize() override { m_sized = true; }
|
||||
void computeBaseline() override { m_baselined = true; }
|
||||
KDPoint positionOfChild(LayoutNode * child) override {
|
||||
assert(false);
|
||||
return KDPointZero;
|
||||
}
|
||||
|
||||
private:
|
||||
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override {}
|
||||
};
|
||||
|
||||
class AllocationFailedLayoutRef : public LayoutReference<AllocationFailedLayoutNode> {
|
||||
|
||||
@@ -1,59 +1,64 @@
|
||||
#ifndef POINCARE_CHAR_LAYOUT_NODE_H
|
||||
#define POINCARE_CHAR_LAYOUT_NODE_H
|
||||
|
||||
#include <poincare/layout_reference.h>
|
||||
#include <poincare/layout_node.h>
|
||||
#include <poincare/layout_cursor.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
#include <poincare/layout_node.h>
|
||||
#include <poincare/layout_reference.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
class CharLayoutNode : public LayoutNode {
|
||||
public:
|
||||
CharLayoutNode() : LayoutNode() {}
|
||||
size_t size() const override {
|
||||
return sizeof(CharLayoutNode);
|
||||
}
|
||||
CharLayoutNode() :
|
||||
LayoutNode(),
|
||||
m_char('a'),
|
||||
m_fontSize(KDText::FontSize::Large)
|
||||
{}
|
||||
void setChar(char c) { m_char = c; }
|
||||
void setFontSize(KDText::FontSize fontSize) { m_fontSize = fontSize; }
|
||||
|
||||
// LayoutNode
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override {
|
||||
return LayoutEngine::writeOneCharInBuffer(buffer, bufferSize, m_char);
|
||||
}
|
||||
void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) override;
|
||||
void moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) override;
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(CharLayoutNode); }
|
||||
int numberOfChildren() const override { return 0; }
|
||||
|
||||
void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) override {
|
||||
if (cursor->position() == LayoutCursor::Position::Right) {
|
||||
cursor->setPosition(LayoutCursor::Position::Left);
|
||||
return;
|
||||
}
|
||||
LayoutNode * parentNode = parent();
|
||||
if (parentNode != nullptr) {
|
||||
parentNode->moveCursorLeft(cursor, shouldRecomputeLayout);
|
||||
}
|
||||
}
|
||||
|
||||
void moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) override {
|
||||
if (cursor->position() == LayoutCursor::Position::Left) {
|
||||
cursor->setPosition(LayoutCursor::Position::Right);
|
||||
return;
|
||||
}
|
||||
LayoutNode * parentNode = parent();
|
||||
if (parentNode != nullptr) {
|
||||
parentNode->moveCursorRight(cursor, shouldRecomputeLayout);
|
||||
}
|
||||
}
|
||||
|
||||
#if TREE_LOG
|
||||
const char * description() const override {
|
||||
static char Description[] = "Char a";
|
||||
Description[5] = m_char;
|
||||
return Description;
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// LayoutNode
|
||||
void computeSize() override;
|
||||
void computeBaseline() override;
|
||||
KDPoint positionOfChild(LayoutNode * child) override {
|
||||
assert(false);
|
||||
return KDPointZero;
|
||||
}
|
||||
|
||||
void setChar(char c) { m_char = c; }
|
||||
private:
|
||||
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override;
|
||||
char m_char;
|
||||
KDText::FontSize m_fontSize;
|
||||
};
|
||||
|
||||
class CharLayoutRef : public LayoutReference<CharLayoutNode> {
|
||||
public:
|
||||
CharLayoutRef(char c) : LayoutReference<CharLayoutNode>() {
|
||||
CharLayoutRef(char c, KDText::FontSize fontSize = KDText::FontSize::Large) :
|
||||
LayoutReference<CharLayoutNode>()
|
||||
{
|
||||
if (!(this->node()->isAllocationFailure())) {
|
||||
this->typedNode()->setChar(c);
|
||||
this->typedNode()->setFontSize(fontSize);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
/* WARNING: A HorizontalLayout should never have a HorizontalLayout child. For
|
||||
* instance, use addOrMergeChildAtIndex to add a LayoutNode safely. */
|
||||
|
||||
class HorizontalLayoutNode : public LayoutNode {
|
||||
public:
|
||||
HorizontalLayoutNode() :
|
||||
@@ -14,72 +17,34 @@ public:
|
||||
m_numberOfChildren(0)
|
||||
{}
|
||||
|
||||
size_t size() const override {
|
||||
return sizeof(HorizontalLayoutNode);
|
||||
}
|
||||
// LayoutNode
|
||||
int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const override;
|
||||
void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) override;
|
||||
void moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) override;
|
||||
|
||||
// TreeNode
|
||||
size_t size() const override { return sizeof(HorizontalLayoutNode); }
|
||||
int numberOfChildren() const override { return m_numberOfChildren; }
|
||||
void incrementNumberOfChildren(int increment = 1) override { m_numberOfChildren+= increment; }
|
||||
void decrementNumberOfChildren(int decrement = 1) override {
|
||||
assert(m_numberOfChildren > 0);
|
||||
assert(m_numberOfChildren >= decrement);
|
||||
m_numberOfChildren-= decrement;
|
||||
}
|
||||
void eraseNumberOfChildren() override {
|
||||
m_numberOfChildren = 0;
|
||||
}
|
||||
|
||||
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<LayoutNode *>(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<LayoutNode *>(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);
|
||||
}
|
||||
}
|
||||
|
||||
void eraseNumberOfChildren() override { m_numberOfChildren = 0; }
|
||||
#if TREE_LOG
|
||||
const char * description() const override {
|
||||
return "Horizontal Layout";
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// LayoutNode
|
||||
void computeSize() override;
|
||||
void computeBaseline() override;
|
||||
KDPoint positionOfChild(LayoutNode * l) override;
|
||||
|
||||
private:
|
||||
void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) override {}
|
||||
int m_numberOfChildren;
|
||||
};
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ public:
|
||||
bool isEquivalentTo(LayoutCursor cursor);
|
||||
|
||||
/* Position */
|
||||
int middleLeftPoint();
|
||||
KDPoint middleLeftPoint();
|
||||
|
||||
/* Move */
|
||||
void moveLeft(bool * shouldRecomputeLayout);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#ifndef POINCARE_LAYOUT_NODE_H
|
||||
#define POINCARE_LAYOUT_NODE_H
|
||||
|
||||
#include "tree_node.h"
|
||||
#include <poincare/print_float.h>
|
||||
#include <poincare/tree_node.h>
|
||||
#include <kandinsky.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
@@ -9,6 +11,30 @@ class LayoutCursor;
|
||||
|
||||
class LayoutNode : public TreeNode {
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
LayoutNode() :
|
||||
TreeNode(),
|
||||
m_baseline(0),
|
||||
m_frame(KDRectZero),
|
||||
m_baselined(false),
|
||||
m_positioned(false),
|
||||
m_sized(false)
|
||||
{
|
||||
}
|
||||
|
||||
// Rendering
|
||||
void draw(KDContext * ctx, KDPoint p, KDColor expressionColor = KDColorBlack, KDColor backgroundColor = KDColorWhite);
|
||||
KDPoint origin();
|
||||
KDPoint absoluteOrigin();
|
||||
KDSize layoutSize();
|
||||
KDCoordinate baseline();
|
||||
virtual void invalidAllSizesPositionsAndBaselines();
|
||||
|
||||
// Serialization
|
||||
virtual int writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits = PrintFloat::k_numberOfStoredSignificantDigits) const = 0;
|
||||
|
||||
// TreeNode
|
||||
static TreeNode * FailedAllocationStaticNode();
|
||||
TreeNode * failedAllocationStaticNode() override { return FailedAllocationStaticNode(); }
|
||||
static int AllocationFailureNodeIdentifier() {
|
||||
@@ -18,15 +44,10 @@ public:
|
||||
return AllocationFailureNodeIdentifier();
|
||||
}
|
||||
|
||||
/* Hierarchy */
|
||||
// Hierarchy
|
||||
LayoutNode * parent() const { return static_cast<LayoutNode *>(parentTree()); }
|
||||
|
||||
/* Rendering */
|
||||
void draw();
|
||||
int origin();
|
||||
int absoluteOrigin();
|
||||
|
||||
/* Tree navigation */
|
||||
// Tree navigation
|
||||
virtual void moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) {}
|
||||
virtual void moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) {}
|
||||
virtual void moveCursorUp(LayoutCursor * cursor, bool * shouldRecomputeLayout, bool equivalentPositionVisited = false) {}
|
||||
@@ -36,6 +57,7 @@ public:
|
||||
LayoutNode * childAtIndex(int i) { return static_cast<LayoutNode *>(childTreeAtIndex(i)); }
|
||||
|
||||
protected:
|
||||
// Iterators
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator(LayoutNode * node) : m_node(node) {}
|
||||
@@ -62,8 +84,21 @@ protected:
|
||||
};
|
||||
DirectChildren children() { return DirectChildren(this); }
|
||||
|
||||
// Sizing and positioning
|
||||
virtual void computeSize() = 0;
|
||||
virtual void computeBaseline() = 0;
|
||||
virtual KDPoint positionOfChild(LayoutNode * child) = 0;
|
||||
|
||||
/* m_baseline is the signed vertical distance from the top of the layout to
|
||||
* the fraction bar of an hypothetical fraction sibling layout. If the top of
|
||||
* the layout is under that bar, the baseline is negative. */
|
||||
KDCoordinate m_baseline;
|
||||
KDRect m_frame;
|
||||
bool m_baselined;
|
||||
bool m_positioned;
|
||||
bool m_sized;
|
||||
private:
|
||||
virtual void render() {};
|
||||
virtual void render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -33,11 +33,11 @@ public:
|
||||
TreeReference<T>::replaceChildAtIndex(oldChildIndex, newChild);
|
||||
}
|
||||
|
||||
int layoutOrigin() {
|
||||
KDPoint layoutOrigin() {
|
||||
return this->typedNode()->layoutOrigin();
|
||||
}
|
||||
|
||||
int absoluteOrigin() {
|
||||
KDPoint absoluteOrigin() {
|
||||
return this->typedNode()->absoluteOrigin();
|
||||
}
|
||||
};
|
||||
|
||||
45
poincare/src/char_layout_node.cpp
Normal file
45
poincare/src/char_layout_node.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <poincare/char_layout_node.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
void CharLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) {
|
||||
if (cursor->position() == LayoutCursor::Position::Right) {
|
||||
cursor->setPosition(LayoutCursor::Position::Left);
|
||||
return;
|
||||
}
|
||||
LayoutNode * parentNode = parent();
|
||||
if (parentNode != nullptr) {
|
||||
parentNode->moveCursorLeft(cursor, shouldRecomputeLayout);
|
||||
}
|
||||
}
|
||||
|
||||
void CharLayoutNode::moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) {
|
||||
if (cursor->position() == LayoutCursor::Position::Left) {
|
||||
cursor->setPosition(LayoutCursor::Position::Right);
|
||||
return;
|
||||
}
|
||||
LayoutNode * parentNode = parent();
|
||||
if (parentNode != nullptr) {
|
||||
parentNode->moveCursorRight(cursor, shouldRecomputeLayout);
|
||||
}
|
||||
}
|
||||
|
||||
// Sizing and positioning
|
||||
void CharLayoutNode::computeSize() {
|
||||
assert(!m_sized);
|
||||
m_frame.setSize(KDText::charSize(m_fontSize));
|
||||
m_sized = true;
|
||||
}
|
||||
|
||||
void CharLayoutNode::computeBaseline() {
|
||||
assert(!m_baselined);
|
||||
m_baseline = (KDText::charSize(m_fontSize).height()+1)/2; //TODO +1 ?
|
||||
m_baselined = true;
|
||||
}
|
||||
|
||||
void CharLayoutNode::render(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
|
||||
char string[2] = {m_char, 0};
|
||||
ctx->drawString(string, p, m_fontSize, expressionColor, backgroundColor);
|
||||
}
|
||||
|
||||
}
|
||||
104
poincare/src/horizontal_layout_node.cpp
Normal file
104
poincare/src/horizontal_layout_node.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
#include <poincare/horizontal_layout_node.h>
|
||||
#include <poincare/layout_engine.h>
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
static inline KDCoordinate max(KDCoordinate c1, KDCoordinate c2) { return c1 > c2 ? c1 : c2; }
|
||||
|
||||
int HorizontalLayoutNode::writeTextInBuffer(char * buffer, int bufferSize, int numberOfSignificantDigits) const {
|
||||
if (numberOfChildren() == 0) {
|
||||
if (bufferSize == 0) {
|
||||
return -1;
|
||||
}
|
||||
buffer[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
return LayoutEngine::writeInfixExpressionLayoutTextInBuffer(this, buffer, bufferSize, numberOfSignificantDigits, "");
|
||||
}
|
||||
|
||||
void HorizontalLayoutNode::moveCursorLeft(LayoutCursor * cursor, bool * shouldRecomputeLayout) {
|
||||
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<LayoutNode *>(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<LayoutNode *>(childTreeAtIndex(childIndex-1)));
|
||||
cursor->setPosition(LayoutCursor::Position::Right);
|
||||
cursor->moveLeft(shouldRecomputeLayout);
|
||||
}
|
||||
|
||||
void HorizontalLayoutNode::moveCursorRight(LayoutCursor * cursor, bool * shouldRecomputeLayout) {
|
||||
//TODO
|
||||
LayoutNode * parentNode = parent();
|
||||
if (parentNode != nullptr) {
|
||||
parentNode->moveCursorRight(cursor, shouldRecomputeLayout);
|
||||
}
|
||||
}
|
||||
|
||||
KDSize HorizontalLayoutNode::computeSize() {
|
||||
assert(!m_sized);
|
||||
KDCoordinate totalWidth = 0;
|
||||
KDCoordinate maxUnderBaseline = 0;
|
||||
KDCoordinate maxAboveBaseline = 0;
|
||||
for (LayoutNode * l : directChildren()) {
|
||||
KDSize childSize = l->size();
|
||||
totalWidth += childSize.width();
|
||||
maxUnderBaseline = max(maxUnderBaseline, childSize.height() - l->baseline());
|
||||
maxAboveBaseline = max(maxAboveBaseline, l->baseline());
|
||||
}
|
||||
m_frame.setSize(KDSize(totalWidth, maxUnderBaseline + maxAboveBaseline));
|
||||
m_sized = true;
|
||||
}
|
||||
|
||||
void HorizontalLayoutNode::computeBaseline() {
|
||||
assert(!m_baselined);
|
||||
m_baseline = 0;
|
||||
for (LayoutNode * l : directChildren()) {
|
||||
m_baseline = max(m_baseline, l->baseline());
|
||||
}
|
||||
m_baselined = true;
|
||||
}
|
||||
|
||||
KDPoint HorizontalLayoutNode::positionOfChild(LayoutNode * l) {
|
||||
assert(hasChild(l));
|
||||
KDCoordinate x = 0;
|
||||
int index = indexOfChild(l);
|
||||
assert(index > -1);
|
||||
if (index > 0) {
|
||||
LayoutNode * previousChild = child(index-1);
|
||||
x = previousChild->origin().x() + previousChild->size().width();
|
||||
}
|
||||
KDCoordinate y = baseline() - l->baseline();
|
||||
return KDPoint(x, y);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,8 +14,8 @@ bool LayoutCursor::isEquivalentTo(LayoutCursor cursor) {
|
||||
|
||||
/* Position */
|
||||
|
||||
int LayoutCursor::middleLeftPoint() {
|
||||
int layoutOrigin = layoutReference().absoluteOrigin();
|
||||
KDPoint LayoutCursor::middleLeftPoint() {
|
||||
KDPoint layoutOrigin = layoutReference().absoluteOrigin();
|
||||
return layoutOrigin;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,39 +4,65 @@
|
||||
|
||||
namespace Poincare {
|
||||
|
||||
TreeNode * LayoutNode::FailedAllocationStaticNode() {
|
||||
return LayoutRef::FailedAllocationStaticNode();
|
||||
}
|
||||
// Rendering
|
||||
|
||||
void LayoutNode::draw() {
|
||||
for (LayoutNode * child : children()) {
|
||||
child->draw();
|
||||
void LayoutNode::draw(KDContext * ctx, KDPoint p, KDColor expressionColor, KDColor backgroundColor) {
|
||||
for (LayoutNode * l : children()) {
|
||||
l->draw(ctx, p, expressionColor, backgroundColor);
|
||||
}
|
||||
render();
|
||||
render(ctx, absoluteOrigin().translatedBy(p), expressionColor, backgroundColor);
|
||||
}
|
||||
|
||||
int LayoutNode::origin() {
|
||||
LayoutNode * parentLayout = parent();
|
||||
if (parentLayout == nullptr) {
|
||||
KDPoint LayoutNode::origin() {
|
||||
LayoutNode * p = parent();
|
||||
if (p != nullptr) {
|
||||
return absoluteOrigin();
|
||||
} else {
|
||||
return 1; //KDPoint(absoluteOrigin().x() - parentLayout->absoluteOrigin().x(), absoluteOrigin().y() - parentLayout->absoluteOrigin().y());
|
||||
return KDPoint(absoluteOrigin().x() - p->absoluteOrigin().x(),
|
||||
absoluteOrigin().y() - p->absoluteOrigin().y());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LayoutNode::absoluteOrigin() {
|
||||
/*if (!m_positioned) {
|
||||
LayoutNode * parentLayout = parent();
|
||||
if (parentLayout != nullptr) {
|
||||
m_frame.setOrigin(parentLayout->absoluteOrigin().translatedBy(parentLayout->positionOfChild(this)));
|
||||
KDPoint LayoutNode::absoluteOrigin() {
|
||||
LayoutNode * p = parent();
|
||||
if (!m_positioned) {
|
||||
if (p != nullptr) {
|
||||
m_frame.setOrigin(p->absoluteOrigin().translatedBy(p->positionOfChild(this)));
|
||||
} else {
|
||||
m_frame.setOrigin(KDPointZero);
|
||||
}
|
||||
m_positioned = true;
|
||||
}
|
||||
return m_frame.origin();*/
|
||||
return 1;
|
||||
return m_frame.origin();
|
||||
}
|
||||
|
||||
KDSize LayoutNode::layoutSize() {
|
||||
if (!m_sized) {
|
||||
computeSize();
|
||||
}
|
||||
return m_frame.size();
|
||||
}
|
||||
|
||||
KDCoordinate LayoutNode::baseline() {
|
||||
if (!m_baselined) {
|
||||
computeBaseline();
|
||||
}
|
||||
return m_baseline;
|
||||
}
|
||||
|
||||
void LayoutNode::invalidAllSizesPositionsAndBaselines() {
|
||||
m_sized = false;
|
||||
m_positioned = false;
|
||||
m_baselined = false;
|
||||
for (LayoutNode * l : children()) {
|
||||
l->invalidAllSizesPositionsAndBaselines();
|
||||
}
|
||||
}
|
||||
|
||||
// TreeNode
|
||||
|
||||
TreeNode * LayoutNode::FailedAllocationStaticNode() {
|
||||
return LayoutRef::FailedAllocationStaticNode();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user