From a8780999f23515d488c5622c8f2f9c95c36b3750 Mon Sep 17 00:00:00 2001 From: laser-shark Date: Tue, 26 May 2020 21:54:16 +0200 Subject: [PATCH 1/4] Try calling backend/Calculator from CalculatorInput --- backend/Calculator.cpp | 1 + gui/CalculatorApp.cpp | 11 +---------- gui/CalculatorApp.h | 1 - gui/CalculatorInput.cpp | 16 +++++++++++++--- gui/CalculatorInput.h | 5 +++++ 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/backend/Calculator.cpp b/backend/Calculator.cpp index ccb917f..e030bb7 100644 --- a/backend/Calculator.cpp +++ b/backend/Calculator.cpp @@ -12,6 +12,7 @@ void Calculator::calculate(std::string s) { // if ip is a stringstream, we have to dynamically cast it to one, because // it is saved as pointer to the base class (istream) if (typeid(*ip) == typeid(stringstream)){ + std::cout << "we are here" << std::cout; *(dynamic_cast(ip)) << s; } else { throw "calculate() can't be called"; diff --git a/gui/CalculatorApp.cpp b/gui/CalculatorApp.cpp index be50501..a126951 100644 --- a/gui/CalculatorApp.cpp +++ b/gui/CalculatorApp.cpp @@ -6,7 +6,7 @@ CalculatorApp::CalculatorApp(SDL_Window *win, SDL_Renderer *ren) : App(win, ren) { // widget for memory TextOutput *memory = new TextOutput{ - win, ren, 30, 30, 600, 400, currentMemory(), 24 + win, ren, 30, 30, 600, 400, "", 24 }; // widget for input prompt @@ -21,12 +21,3 @@ CalculatorApp::CalculatorApp(SDL_Window *win, SDL_Renderer *ren) : App(win, ren) widgets.push_back(prompt); widgets.push_back(input); } - -// TODO: we don't need this here, CalculatorInput takes care of it -std::string CalculatorApp::currentMemory() { - // TODO: call calculator and get memory - // or if it's not the same instance every time, maybe have a separate memory - // as member of Calculator App, that will be passed every time a new - // Calculator App instance is made - return "[m1] 15.2\n[m2] 122\n[m3] 99"; -} diff --git a/gui/CalculatorApp.h b/gui/CalculatorApp.h index 2d50338..1b9a6ed 100644 --- a/gui/CalculatorApp.h +++ b/gui/CalculatorApp.h @@ -8,7 +8,6 @@ class CalculatorApp : public App { public: CalculatorApp(SDL_Window *window, SDL_Renderer *renderer); - std::string currentMemory(); }; #endif diff --git a/gui/CalculatorInput.cpp b/gui/CalculatorInput.cpp index eaca7f2..a243db2 100644 --- a/gui/CalculatorInput.cpp +++ b/gui/CalculatorInput.cpp @@ -6,6 +6,17 @@ CalculatorInput::CalculatorInput( std::string text, int fontSize, TextOutput *output ) : LineInput(w, r, x1, y1, x2, y2, text, fontSize) { this->output = output; + + this->calculator = new Calculator{this->stream}; + + /* + std::stringstream stream; + Calculator C(&stream); + C.calculate("2 + 3"); + std::cout << C.getMemory() << std::endl; + C.calculate("4 / 1.5"); + std::cout << C.getMemory() << std::endl; + */ } App * CalculatorInput::handleEvent(SDL_Event event) { @@ -15,9 +26,8 @@ App * CalculatorInput::handleEvent(SDL_Event event) { } if(event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_RETURN) { - // TODO: call math-tool calculate_single, then call math-tool get_current_memory(), - // then assign the result of that to this->output - this->output->setText("[m1] 15\n[m2] 27.2"); + this->calculator->calculate(this->text); + this->output->setText(this->calculator->getMemory()); this->text = ""; } return nextApp; // if it's nullptr, we want to stay in the calculator diff --git a/gui/CalculatorInput.h b/gui/CalculatorInput.h index 83d6038..9dd9d41 100644 --- a/gui/CalculatorInput.h +++ b/gui/CalculatorInput.h @@ -1,12 +1,17 @@ #ifndef _CALCULATOR_INPUT_H_ #define _CALCULATOR_INPUT_H_ +#include "backend/Calculator.h" #include "TextOutput.h" #include "LineInput.h" +class Calculator; + class CalculatorInput : public LineInput{ private: TextOutput *output; + std::stringstream *stream; + Calculator *calculator; public: CalculatorInput( SDL_Window *w, SDL_Renderer *r, int x1, int y1, int x2, int y2, From e801bf261e610bb544b1efbe6af81c019a8e8b89 Mon Sep 17 00:00:00 2001 From: laser-shark Date: Tue, 26 May 2020 22:57:45 +0200 Subject: [PATCH 2/4] Use backend/Calculator in CalculatorInput --- backend/Calculator.cpp | 23 +++++++++++++++++++---- backend/Calculator.h | 6 ++++++ gui/CalculatorApp.cpp | 14 ++++++++++++-- gui/CalculatorApp.h | 12 ++++++++++-- gui/CalculatorInput.cpp | 20 ++------------------ gui/CalculatorInput.h | 4 +--- gui/FunctionPlotterApp.h | 4 ++-- gui/GeometryApp.h | 4 ++-- 8 files changed, 54 insertions(+), 33 deletions(-) diff --git a/backend/Calculator.cpp b/backend/Calculator.cpp index e030bb7..6b4a288 100644 --- a/backend/Calculator.cpp +++ b/backend/Calculator.cpp @@ -1,18 +1,33 @@ #include "Calculator.h" +Calculator::Calculator() { + std::stringstream *s = new stringstream; + this->ip = s; + this->ts = new TokenStream(ip); + this->parser = new Parser(ts); + this->ownsStream = true; // we own the stream and have to delete it +} + Calculator::Calculator(std::istream *ip) { this->ip = ip; - TokenStream *ts = new TokenStream{ip}; - Parser *ps = new Parser{ts}; - this->parser = ps; + this->ts = new TokenStream{ip}; + this->parser = new Parser{ts}; + this->ownsStream = false; // we don't own the stream and can't delete it +} + +Calculator::~Calculator() { + if (this->ownsStream) { + delete this->ip; + } + delete this->ts; + delete this->parser; } void Calculator::calculate(std::string s) { // if ip is a stringstream, we have to dynamically cast it to one, because // it is saved as pointer to the base class (istream) if (typeid(*ip) == typeid(stringstream)){ - std::cout << "we are here" << std::cout; *(dynamic_cast(ip)) << s; } else { throw "calculate() can't be called"; diff --git a/backend/Calculator.h b/backend/Calculator.h index 65f1c87..0dd8315 100644 --- a/backend/Calculator.h +++ b/backend/Calculator.h @@ -7,12 +7,18 @@ #include "Parser.h" #include "TokenStream.h" + class Calculator { private: std::istream *ip; + TokenStream *ts; Parser *parser; + bool ownsStream; public: + Calculator(); Calculator(std::istream *ip); + ~Calculator(); + void calculate(std::string s); std::string getMemory(); }; diff --git a/gui/CalculatorApp.cpp b/gui/CalculatorApp.cpp index a126951..0a900c8 100644 --- a/gui/CalculatorApp.cpp +++ b/gui/CalculatorApp.cpp @@ -6,7 +6,7 @@ CalculatorApp::CalculatorApp(SDL_Window *win, SDL_Renderer *ren) : App(win, ren) { // widget for memory TextOutput *memory = new TextOutput{ - win, ren, 30, 30, 600, 400, "", 24 + win, ren, 30, 30, 600, 400, "", 18 }; // widget for input prompt @@ -15,9 +15,19 @@ CalculatorApp::CalculatorApp(SDL_Window *win, SDL_Renderer *ren) : App(win, ren) }; // widget for input - CalculatorInput *input = new CalculatorInput{win, ren, 300, 450, 600, 500, "", 24, memory}; + this->calculator = new Calculator{}; + CalculatorInput *input = new CalculatorInput{ + win, ren, 300, 450, 600, 500, "", 24, memory, this->calculator + }; + widgets.push_back(memory); widgets.push_back(prompt); widgets.push_back(input); } + + +CalculatorApp::~CalculatorApp() { + delete this->calculator; + // deletion of widgets happens in superclass destructor +} diff --git a/gui/CalculatorApp.h b/gui/CalculatorApp.h index 1b9a6ed..fd84bd7 100644 --- a/gui/CalculatorApp.h +++ b/gui/CalculatorApp.h @@ -1,13 +1,21 @@ -#ifndef _CALCULATOR_H_ -#define _CALCULATOR_H_ +#ifndef _CALCULATOR_APP_H_ +#define _CALCULATOR_APP_H_ #include +#include "backend/Calculator.h" #include "App.h" + +class Calculator; + + class CalculatorApp : public App { +private: + Calculator *calculator; public: CalculatorApp(SDL_Window *window, SDL_Renderer *renderer); + virtual ~CalculatorApp(); }; #endif diff --git a/gui/CalculatorInput.cpp b/gui/CalculatorInput.cpp index a243db2..2969db0 100644 --- a/gui/CalculatorInput.cpp +++ b/gui/CalculatorInput.cpp @@ -3,20 +3,10 @@ CalculatorInput::CalculatorInput( SDL_Window *w, SDL_Renderer *r, int x1, int y1, int x2, int y2, - std::string text, int fontSize, TextOutput *output + std::string text, int fontSize, TextOutput *output, Calculator *calculator ) : LineInput(w, r, x1, y1, x2, y2, text, fontSize) { this->output = output; - - this->calculator = new Calculator{this->stream}; - - /* - std::stringstream stream; - Calculator C(&stream); - C.calculate("2 + 3"); - std::cout << C.getMemory() << std::endl; - C.calculate("4 / 1.5"); - std::cout << C.getMemory() << std::endl; - */ + this->calculator = calculator; } App * CalculatorInput::handleEvent(SDL_Event event) { @@ -32,9 +22,3 @@ App * CalculatorInput::handleEvent(SDL_Event event) { } return nextApp; // if it's nullptr, we want to stay in the calculator } - - -double CalculatorInput::calculate(std::string text) { - // TODO: call the math-tool Calculator here - return 14.2; -} diff --git a/gui/CalculatorInput.h b/gui/CalculatorInput.h index 9dd9d41..2287560 100644 --- a/gui/CalculatorInput.h +++ b/gui/CalculatorInput.h @@ -10,16 +10,14 @@ class Calculator; class CalculatorInput : public LineInput{ private: TextOutput *output; - std::stringstream *stream; Calculator *calculator; public: CalculatorInput( SDL_Window *w, SDL_Renderer *r, int x1, int y1, int x2, int y2, - std::string text, int fontSize, TextOutput *output + std::string text, int fontSize, TextOutput *output, Calculator *c ); virtual App * handleEvent(SDL_Event event); - double calculate(std::string text); }; #endif diff --git a/gui/FunctionPlotterApp.h b/gui/FunctionPlotterApp.h index 310eccd..ed25e2c 100644 --- a/gui/FunctionPlotterApp.h +++ b/gui/FunctionPlotterApp.h @@ -1,5 +1,5 @@ -#ifndef _FUNCTION_PLOTTER_H_ -#define _FUNCTION_PLOTTER_H_ +#ifndef _FUNCTION_PLOTTER_APP_H_ +#define _FUNCTION_PLOTTER_APP_H_ #include "App.h" #include "Graph.h" diff --git a/gui/GeometryApp.h b/gui/GeometryApp.h index 93abaf4..1c3eaaa 100644 --- a/gui/GeometryApp.h +++ b/gui/GeometryApp.h @@ -1,5 +1,5 @@ -#ifndef _GEOMETRY_H_ -#define _GEOMETRY_H_ +#ifndef _GEOMETRY_APP_H_ +#define _GEOMETRY_APP_H_ #include "App.h" #include "Graph.h" From 3ce9a838c2a1d741a80d2f5fe71e3f0a819e794a Mon Sep 17 00:00:00 2001 From: laser-shark Date: Tue, 26 May 2020 23:03:57 +0200 Subject: [PATCH 3/4] Calculate line spacing dynamically --- gui/render_text.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gui/render_text.cpp b/gui/render_text.cpp index 5d5d8cc..1b572c0 100644 --- a/gui/render_text.cpp +++ b/gui/render_text.cpp @@ -17,10 +17,11 @@ void render_text( // helper variables int textW = xEnd - xStart; int textH = yEnd - yStart; + int lineHeight = fontSize * 1.4; // determine space between lines // starting point of message rectangle int startX = xStart; - int startY = yStart - 70; + int startY = yStart - lineHeight; // text has to be converted to istream in order to call getline std::stringstream ss(text); @@ -28,7 +29,7 @@ void render_text( // break at newline and render single line while(getline(ss, textToRender, '\n')) { - startY += 70; + startY += lineHeight; SDL_Surface *textSurface = TTF_RenderText_Solid( font, textToRender.c_str(), color ); From d07efd19cc8a65c47608ee4c54e6a8d6dcbfb152 Mon Sep 17 00:00:00 2001 From: laser-shark Date: Tue, 26 May 2020 23:11:34 +0200 Subject: [PATCH 4/4] Prevent text on the screen from overflowing (very basic scrolling) --- gui/render_text.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gui/render_text.cpp b/gui/render_text.cpp index 1b572c0..37b1d39 100644 --- a/gui/render_text.cpp +++ b/gui/render_text.cpp @@ -29,6 +29,12 @@ void render_text( // break at newline and render single line while(getline(ss, textToRender, '\n')) { + if (startY >= yEnd) { + // reset startY + startY = yStart - lineHeight; + // clear screen + SDL_RenderClear(renderer); + } startY += lineHeight; SDL_Surface *textSurface = TTF_RenderText_Solid( font, textToRender.c_str(), color