mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 00:37:25 +01:00
[poincare] Separate the layout logic
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/fraction.h>
|
||||
#include <poincare/integer.h>
|
||||
#include <poincare/number.h>
|
||||
#include <poincare/power.h>
|
||||
|
||||
#endif
|
||||
|
||||
15
poincare/include/poincare/addition.h
Normal file
15
poincare/include/poincare/addition.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef POINCARE_ADDITION_H
|
||||
#define POINCARE_ADDITION_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
|
||||
class Addition : public Expression {
|
||||
public:
|
||||
Addition(Expression * first_operand, Expression * second_operand);
|
||||
virtual ExpressionLayout * layout();
|
||||
virtual float approximate();
|
||||
private:
|
||||
Expression * m_children[2];
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,30 +1,26 @@
|
||||
#ifndef POINCARE_EXPRESSION_H
|
||||
#define POINCARE_EXPRESSION_H
|
||||
|
||||
extern "C" {
|
||||
#include <kandinsky.h>
|
||||
}
|
||||
|
||||
class Expression;
|
||||
typedef void (Expression::*ExpressionAction)(void);
|
||||
#include <poincare/expression_layout.h>
|
||||
|
||||
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
|
||||
|
||||
14
poincare/include/poincare/expression_layout.h
Normal file
14
poincare/include/poincare/expression_layout.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef POINCARE_EXPRESSION_LAYOUT_H
|
||||
#define POINCARE_EXPRESSION_LAYOUT_H
|
||||
|
||||
extern "C" {
|
||||
#include <kandinsky.h>
|
||||
}
|
||||
|
||||
class ExpressionLayout {
|
||||
public:
|
||||
virtual void draw() = 0;
|
||||
KDRect m_frame;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef POINCARE_NUMBER_H
|
||||
#define POINCARE_NUMBER_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
|
||||
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
|
||||
34
poincare/src/addition.cpp
Normal file
34
poincare/src/addition.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <poincare/fraction.h>
|
||||
#include <string.h>
|
||||
|
||||
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]);
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -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); } */
|
||||
;
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
#include <poincare/fraction.h>
|
||||
#include <string.h>
|
||||
#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
|
||||
|
||||
@@ -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<Integer *>(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;
|
||||
}
|
||||
|
||||
40
poincare/src/layout/fraction_layout.cpp
Normal file
40
poincare/src/layout/fraction_layout.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <poincare/fraction.h>
|
||||
#include <string.h>
|
||||
#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});
|
||||
}
|
||||
16
poincare/src/layout/fraction_layout.h
Normal file
16
poincare/src/layout/fraction_layout.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef POINCARE_FRACTION_LAYOUT_H
|
||||
#define POINCARE_FRACTION_LAYOUT_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/expression_layout.h>
|
||||
|
||||
class FractionLayout : public ExpressionLayout {
|
||||
public:
|
||||
FractionLayout(Expression * numerator, Expression * denominator);
|
||||
virtual void draw();
|
||||
private:
|
||||
ExpressionLayout * m_numerator;
|
||||
ExpressionLayout * m_denominator;
|
||||
};
|
||||
|
||||
#endif
|
||||
45
poincare/src/layout/horizontal_layout.cpp
Normal file
45
poincare/src/layout/horizontal_layout.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
//#include <string.h>
|
||||
#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]);
|
||||
}
|
||||
*/
|
||||
17
poincare/src/layout/horizontal_layout.h
Normal file
17
poincare/src/layout/horizontal_layout.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef POINCARE_HORIZONTAL_LAYOUT_H
|
||||
#define POINCARE_HORIZONTAL_LAYOUT_H
|
||||
|
||||
#include <poincare/expression.h>
|
||||
#include <poincare/expression_layout.h>
|
||||
|
||||
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
|
||||
28
poincare/src/layout/string_layout.cpp
Normal file
28
poincare/src/layout/string_layout.cpp
Normal file
@@ -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]);
|
||||
}
|
||||
*/
|
||||
14
poincare/src/layout/string_layout.h
Normal file
14
poincare/src/layout/string_layout.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef POINCARE_STRING_LAYOUT_H
|
||||
#define POINCARE_STRING_LAYOUT_H
|
||||
|
||||
#include <poincare/expression_layout.h>
|
||||
|
||||
class StringLayout : public ExpressionLayout {
|
||||
public:
|
||||
StringLayout(const char * string);
|
||||
virtual void draw();
|
||||
private:
|
||||
const char * m_string;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,43 +0,0 @@
|
||||
#include <poincare/number.h>
|
||||
#include <kandinsky/text.h>
|
||||
#include <string.h>
|
||||
|
||||
/*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));
|
||||
}
|
||||
Reference in New Issue
Block a user