From fc08a651ccb10a80efa2a9dd37698f6b0c8df695 Mon Sep 17 00:00:00 2001 From: Romain Goyet Date: Mon, 21 Sep 2015 10:37:22 +0200 Subject: [PATCH] [poincare] Separate the layout logic --- poincare/Makefile | 3 +- poincare/include/poincare.h | 1 - poincare/include/poincare/addition.h | 15 +++++++ poincare/include/poincare/expression.h | 24 +++++----- poincare/include/poincare/expression_layout.h | 14 ++++++ poincare/include/poincare/fraction.h | 5 +-- poincare/include/poincare/integer.h | 7 ++- poincare/include/poincare/number.h | 18 -------- poincare/src/addition.cpp | 34 ++++++++++++++ poincare/src/expression.cpp | 2 + poincare/src/expression_parser.y | 2 +- poincare/src/fraction.cpp | 10 +++++ poincare/src/integer.cpp | 10 +++++ poincare/src/layout/fraction_layout.cpp | 40 +++++++++++++++++ poincare/src/layout/fraction_layout.h | 16 +++++++ poincare/src/layout/horizontal_layout.cpp | 45 +++++++++++++++++++ poincare/src/layout/horizontal_layout.h | 17 +++++++ poincare/src/layout/string_layout.cpp | 28 ++++++++++++ poincare/src/layout/string_layout.h | 14 ++++++ poincare/src/number.cpp | 43 ------------------ 20 files changed, 263 insertions(+), 85 deletions(-) create mode 100644 poincare/include/poincare/addition.h create mode 100644 poincare/include/poincare/expression_layout.h delete mode 100644 poincare/include/poincare/number.h create mode 100644 poincare/src/addition.cpp create mode 100644 poincare/src/layout/fraction_layout.cpp create mode 100644 poincare/src/layout/fraction_layout.h create mode 100644 poincare/src/layout/horizontal_layout.cpp create mode 100644 poincare/src/layout/horizontal_layout.h create mode 100644 poincare/src/layout/string_layout.cpp create mode 100644 poincare/src/layout/string_layout.h delete mode 100644 poincare/src/number.cpp diff --git a/poincare/Makefile b/poincare/Makefile index 461ec1c5d..4eb926a4e 100644 --- a/poincare/Makefile +++ b/poincare/Makefile @@ -1,5 +1,6 @@ SFLAGS += -Ipoincare/include -objs += $(addprefix poincare/src/, expression.o integer.o number.o fraction.o power.o expression_lexer.o expression_parser.o) +objs += $(addprefix poincare/src/, expression.o integer.o fraction.o expression_lexer.o expression_parser.o) +objs += $(addprefix poincare/src/layout/, fraction_layout.o horizontal_layout.o string_layout.o) tests += $(addprefix poincare/test/, integer.cpp) # Even though flex and bison will generate both implementation and headers at diff --git a/poincare/include/poincare.h b/poincare/include/poincare.h index 00d2b93c6..1714634e9 100644 --- a/poincare/include/poincare.h +++ b/poincare/include/poincare.h @@ -4,7 +4,6 @@ #include #include #include -#include #include #endif diff --git a/poincare/include/poincare/addition.h b/poincare/include/poincare/addition.h new file mode 100644 index 000000000..a1e2ab83d --- /dev/null +++ b/poincare/include/poincare/addition.h @@ -0,0 +1,15 @@ +#ifndef POINCARE_ADDITION_H +#define POINCARE_ADDITION_H + +#include + +class Addition : public Expression { + public: + Addition(Expression * first_operand, Expression * second_operand); + virtual ExpressionLayout * layout(); + virtual float approximate(); + private: + Expression * m_children[2]; +}; + +#endif diff --git a/poincare/include/poincare/expression.h b/poincare/include/poincare/expression.h index da2b138b8..3780398da 100644 --- a/poincare/include/poincare/expression.h +++ b/poincare/include/poincare/expression.h @@ -1,30 +1,26 @@ #ifndef POINCARE_EXPRESSION_H #define POINCARE_EXPRESSION_H -extern "C" { -#include -} - -class Expression; -typedef void (Expression::*ExpressionAction)(void); +#include class Expression { public: static Expression * parse(char * string); - void recursiveDraw(); - void recursiveLayout(); - KDRect m_frame; - virtual Expression ** children() = 0; // NULL-terminated - virtual void draw(); - virtual void layout(); + + //virtual Expression ** children() = 0; // NULL-terminated + + virtual ExpressionLayout * createLayout() = 0; // Returned object must be deleted + // TODO: Consider std::unique_ptr - see https://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Ownership_and_Smart_Pointers + /* identicalTo means strictly the same tree. For example, 3+5 is NOT identi- * cal to 5+3. Those are equal, but not identical. */ - virtual bool identicalTo(Expression * e); + //virtual bool identicalTo(Expression * e); //virtual Expression * simplify(); virtual float approximate() = 0; - private: + /*private: void forEachChild(ExpressionAction); + */ }; #endif diff --git a/poincare/include/poincare/expression_layout.h b/poincare/include/poincare/expression_layout.h new file mode 100644 index 000000000..2a1176c1a --- /dev/null +++ b/poincare/include/poincare/expression_layout.h @@ -0,0 +1,14 @@ +#ifndef POINCARE_EXPRESSION_LAYOUT_H +#define POINCARE_EXPRESSION_LAYOUT_H + +extern "C" { +#include +} + +class ExpressionLayout { + public: + virtual void draw() = 0; + KDRect m_frame; +}; + +#endif diff --git a/poincare/include/poincare/fraction.h b/poincare/include/poincare/fraction.h index 6f38e15d4..7fe38d8de 100644 --- a/poincare/include/poincare/fraction.h +++ b/poincare/include/poincare/fraction.h @@ -6,10 +6,9 @@ class Fraction : public Expression { public: Fraction(Expression * numerator, Expression * denominator); - virtual void draw(); - virtual Expression ** children(); +// virtual Expression ** children(); // protected: - virtual void layout(); + virtual ExpressionLayout * createLayout(); virtual float approximate(); private: Expression * m_children[3]; diff --git a/poincare/include/poincare/integer.h b/poincare/include/poincare/integer.h index 15cd99dbb..2655b04ed 100644 --- a/poincare/include/poincare/integer.h +++ b/poincare/include/poincare/integer.h @@ -21,12 +21,11 @@ class Integer : public Expression { Integer operator*(const Integer &other) const; bool operator==(const Integer &other) const; - virtual void draw(); - virtual Expression ** children(); + /*virtual Expression ** children(); virtual bool identicalTo(Expression * e); + */ + virtual ExpressionLayout * createLayout(); virtual float approximate(); - protected: - virtual void layout(); private: /* WARNING: This constructor takes ownership of the bits array and will free it! */ Integer(native_uint_t * digits, uint16_t numberOfDigits); diff --git a/poincare/include/poincare/number.h b/poincare/include/poincare/number.h deleted file mode 100644 index f680ae192..000000000 --- a/poincare/include/poincare/number.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef POINCARE_NUMBER_H -#define POINCARE_NUMBER_H - -#include - -class Number : public Expression { - public: - Number(char * string); - //Number(int v); - virtual void draw(); - virtual Expression ** children(); - protected: - virtual void layout(); - private: - char m_stringValue[16]; -}; - -#endif diff --git a/poincare/src/addition.cpp b/poincare/src/addition.cpp new file mode 100644 index 000000000..deff8d579 --- /dev/null +++ b/poincare/src/addition.cpp @@ -0,0 +1,34 @@ +#include +#include + +static inline KDCoordinate max(KDCoordinate a, KDCoordinate b) { + return (a > b ? a : b); +} + +#define NUMERATOR m_children[0] +#define DENOMINATOR m_children[1] + +#define FRACTION_BORDER_LENGTH 2 +#define FRACTION_LINE_MARGIN 2 +#define FRACTION_LINE_HEIGHT 1 + +Addition::Addition(Expression * first_operand, Expression * second_operand) { + m_children[0] = first_operand; + m_children[1] = second_operand; +} + +Expression ** Fraction::children() { + return m_children; +} + +int Addition::numberOfChildren() { + return 2; +} + +float Addition::approximate() { + return m_children[0]->approximate() + m_children[1]->approximate(); +} + +ExpressionLayout * Addition::layout() { + return HorizontalLayout(m_children[0], "+", m_children[1]); +} diff --git a/poincare/src/expression.cpp b/poincare/src/expression.cpp index 70182352e..25ea59935 100644 --- a/poincare/src/expression.cpp +++ b/poincare/src/expression.cpp @@ -19,6 +19,7 @@ Expression * Expression::parse(char * string) { return expression; } +/* bool Expression::identicalTo(Expression * e) { // By default, two expression are not identical. // This should obviously be overriden in subclasses! @@ -61,3 +62,4 @@ void Expression::draw() { void Expression::layout() { // No-op by default } +*/ diff --git a/poincare/src/expression_parser.y b/poincare/src/expression_parser.y index 92c3f918b..9211fc90c 100644 --- a/poincare/src/expression_parser.y +++ b/poincare/src/expression_parser.y @@ -92,7 +92,7 @@ Root: exp: INTEGER { $$ = new Integer($1); } | exp DIVIDE exp { $$ = new Fraction($1,$3); } - | exp POW exp { $$ = new Power($1,$3); } +/* | exp POW exp { $$ = new Power($1,$3); } */ ; /* diff --git a/poincare/src/fraction.cpp b/poincare/src/fraction.cpp index 8c7c81b62..c6244eca9 100644 --- a/poincare/src/fraction.cpp +++ b/poincare/src/fraction.cpp @@ -1,9 +1,12 @@ #include #include +#include "layout/horizontal_layout.h" +/* static inline KDCoordinate max(KDCoordinate a, KDCoordinate b) { return (a > b ? a : b); } +*/ #define NUMERATOR m_children[0] #define DENOMINATOR m_children[1] @@ -17,11 +20,17 @@ Fraction::Fraction(Expression * numerator, Expression * denominator) { m_children[1] = denominator; m_children[2] = NULL; } +/* Expression ** Fraction::children() { return m_children; } +*/ +ExpressionLayout * Fraction::createLayout() { + return new HorizontalLayout(NUMERATOR, '-', DENOMINATOR); +} +/* void Fraction::layout() { KDRect numFrame = NUMERATOR->m_frame; KDRect denFrame = DENOMINATOR->m_frame; @@ -46,6 +55,7 @@ void Fraction::draw() { KDDrawLine((KDPoint){.x = 0, .y = fractionLineY}, (KDPoint){.x = m_frame.width, .y = fractionLineY}); } +*/ float Fraction::approximate() { // TODO: handle division by zero diff --git a/poincare/src/integer.cpp b/poincare/src/integer.cpp index e0c2eb732..6b777f5d8 100644 --- a/poincare/src/integer.cpp +++ b/poincare/src/integer.cpp @@ -114,6 +114,7 @@ Integer& Integer::operator=(Integer&& other) { other.m_numberOfDigits = 0; other.m_digits = NULL; } + return *this; } Integer Integer::operator+(const Integer &other) const { @@ -167,6 +168,7 @@ Integer Integer::operator*(const Integer &other) const { return Integer(digits, productSize); } +#if 0 bool Integer::identicalTo(Expression * e) { /* FIXME Integer * i = dynamic_cast(e); @@ -186,6 +188,7 @@ void Integer::layout() { void Integer::draw() { // KDDrawString(m_stringValue, KDPOINT(0,0)); } +#endif float Integer::approximate() { union { @@ -227,3 +230,10 @@ float Integer::approximate() { return float_result; } + +ExpressionLayout * Integer::createLayout() { + // 1 - Build string rep' + // 2 - return StringLayout + // FIXME + return nullptr; +} diff --git a/poincare/src/layout/fraction_layout.cpp b/poincare/src/layout/fraction_layout.cpp new file mode 100644 index 000000000..2a2fb4f34 --- /dev/null +++ b/poincare/src/layout/fraction_layout.cpp @@ -0,0 +1,40 @@ +#include +#include +#include "fraction_layout.h" + +static inline KDCoordinate max(KDCoordinate a, KDCoordinate b) { + return (a > b ? a : b); +} + +#define FRACTION_BORDER_LENGTH 2 +#define FRACTION_LINE_MARGIN 2 +#define FRACTION_LINE_HEIGHT 1 + +FractionLayout::FractionLayout(Expression * numerator, Expression * denominator) { + m_numerator = numerator->createLayout(); + m_denominator = denominator->createLayout(); + + KDRect numFrame = m_numerator->m_frame; + KDRect denFrame = m_denominator->m_frame; + + m_frame.x = 0; + m_frame.y = 0; + m_frame.width = max(numFrame.width, denFrame.width) + 2*FRACTION_BORDER_LENGTH; + m_frame.height = numFrame.height + FRACTION_LINE_MARGIN + FRACTION_LINE_HEIGHT + FRACTION_LINE_MARGIN + denFrame.height; + + m_numerator->m_frame.origin.x = (KDCoordinate)((m_frame.width - numFrame.width)/2); + m_numerator->m_frame.origin.y = 0; + + m_denominator->m_frame.origin.x = (KDCoordinate)((m_frame.width - denFrame.width)/2); + m_denominator->m_frame.origin.y = (KDCoordinate)(numFrame.height + 2*FRACTION_LINE_MARGIN + FRACTION_LINE_HEIGHT); +} + +void FractionLayout::draw() { + m_numerator->draw(); + m_denominator->draw(); + + KDCoordinate fractionLineY = m_numerator->m_frame.height + FRACTION_LINE_MARGIN; + + KDDrawLine((KDPoint){.x = 0, .y = fractionLineY}, + (KDPoint){.x = m_frame.width, .y = fractionLineY}); +} diff --git a/poincare/src/layout/fraction_layout.h b/poincare/src/layout/fraction_layout.h new file mode 100644 index 000000000..77897ceaa --- /dev/null +++ b/poincare/src/layout/fraction_layout.h @@ -0,0 +1,16 @@ +#ifndef POINCARE_FRACTION_LAYOUT_H +#define POINCARE_FRACTION_LAYOUT_H + +#include +#include + +class FractionLayout : public ExpressionLayout { + public: + FractionLayout(Expression * numerator, Expression * denominator); + virtual void draw(); + private: + ExpressionLayout * m_numerator; + ExpressionLayout * m_denominator; +}; + +#endif diff --git a/poincare/src/layout/horizontal_layout.cpp b/poincare/src/layout/horizontal_layout.cpp new file mode 100644 index 000000000..9368733e6 --- /dev/null +++ b/poincare/src/layout/horizontal_layout.cpp @@ -0,0 +1,45 @@ +//#include +#include "horizontal_layout.h" + +static inline KDCoordinate max(KDCoordinate a, KDCoordinate b) { + return (a > b ? a : b); +} + +HorizontalLayout::HorizontalLayout(Expression * left_expression, char symbol, Expression * right_expression) { + m_children[0] = left_expression->createLayout(); + m_children[1] = right_expression->createLayout(); + m_symbol = symbol; + /* Perform the layout */ + m_frame.x = 0; + m_frame.y = 0; + m_frame.width = m_children[0]->m_frame.width + 12 + m_children[1]->m_frame.width; // FIXME: 12 is not actually 12 + m_frame.height = max(m_children[0]->m_frame.height, m_children[1]->m_frame.height); // FIXME: height of m_symbol +} + +HorizontalLayout::~HorizontalLayout() { + delete m_children[1]; + delete m_children[2]; +} + +void HorizontalLayout::draw() { + m_children[0]->draw(); + m_children[1]->draw(); +} +/* + +Expression ** Fraction::children() { + return m_children; +} + +int Addition::numberOfChildren() { + return 2; +} + +float Addition::approximate() { + return m_children[0]->approximate() + m_children[1]->approximate(); +} + +ExpressionLayout * Addition::layout() { + return HorizontalLayout(m_children[0], "+", m_children[1]); +} +*/ diff --git a/poincare/src/layout/horizontal_layout.h b/poincare/src/layout/horizontal_layout.h new file mode 100644 index 000000000..ad74ff242 --- /dev/null +++ b/poincare/src/layout/horizontal_layout.h @@ -0,0 +1,17 @@ +#ifndef POINCARE_HORIZONTAL_LAYOUT_H +#define POINCARE_HORIZONTAL_LAYOUT_H + +#include +#include + +class HorizontalLayout : public ExpressionLayout { + public: + HorizontalLayout(Expression * left_expression, char symbol, Expression * right_expression); + ~HorizontalLayout(); + virtual void draw(); + private: + ExpressionLayout * m_children[2]; + char m_symbol; +}; + +#endif diff --git a/poincare/src/layout/string_layout.cpp b/poincare/src/layout/string_layout.cpp new file mode 100644 index 000000000..af7f723be --- /dev/null +++ b/poincare/src/layout/string_layout.cpp @@ -0,0 +1,28 @@ +#include "string_layout.h" + +StringLayout::StringLayout(const char * string) { + m_string = string; + //FIXME: Copy the string? +} + +void StringLayout::draw() { + KDDrawString(m_string, (KDPoint){.x = 0, .y = 0}); +} +/* + +Expression ** Fraction::children() { + return m_children; +} + +int Addition::numberOfChildren() { + return 2; +} + +float Addition::approximate() { + return m_children[0]->approximate() + m_children[1]->approximate(); +} + +ExpressionLayout * Addition::layout() { + return HorizontalLayout(m_children[0], "+", m_children[1]); +} +*/ diff --git a/poincare/src/layout/string_layout.h b/poincare/src/layout/string_layout.h new file mode 100644 index 000000000..65fae5c95 --- /dev/null +++ b/poincare/src/layout/string_layout.h @@ -0,0 +1,14 @@ +#ifndef POINCARE_STRING_LAYOUT_H +#define POINCARE_STRING_LAYOUT_H + +#include + +class StringLayout : public ExpressionLayout { + public: + StringLayout(const char * string); + virtual void draw(); + private: + const char * m_string; +}; + +#endif diff --git a/poincare/src/number.cpp b/poincare/src/number.cpp deleted file mode 100644 index f7bf76183..000000000 --- a/poincare/src/number.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include - -/*Number::Number(int v) : m_value(v) { - for (int i=0; i<16; i++) { - m_stringValue[i] = 0; - } - - int value = v; - for (int i=0; i<15; i++) { - int digit = value - 10*(value/10); - m_stringValue[i] = '0' + digit; - value = value/10; - if (value == 0) { - break; - } - } -}*/ - -Number::Number(char * string) { - // FIXME: use strdup - memset(m_stringValue, 0, 16); - for (int i=0;i<15;i++) { - if (string[i] == 0) { - break; - } - m_stringValue[i] = string[i]; - } -} - - -Expression ** Number::children() { - return NULL; -} - -void Number::layout() { - m_frame.size = KDStringSize(m_stringValue); -} - -void Number::draw() { - KDDrawString(m_stringValue, KDPOINT(0,0)); -}