From 42a76739f2d64679d779edbcf40a8844ae34d5a9 Mon Sep 17 00:00:00 2001 From: cxl Date: Mon, 25 Jan 2016 11:41:34 +0000 Subject: [PATCH] .examples git-svn-id: svn://ultimatepp.org/upp/trunk@9434 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- examples/AndroidMath/MemoryManager.h | 2 +- examples/EyeCare/EyeCare.upp | 2 +- examples/FnGraph/FnGraph.upp | 12 ++ examples/FnGraph/init | 5 + examples/FnGraph/main.cpp | 171 +++++++++++++++++++++++++++ examples/UWord/UWord.upp | 3 +- 6 files changed, 191 insertions(+), 4 deletions(-) create mode 100644 examples/FnGraph/FnGraph.upp create mode 100644 examples/FnGraph/init create mode 100644 examples/FnGraph/main.cpp diff --git a/examples/AndroidMath/MemoryManager.h b/examples/AndroidMath/MemoryManager.h index b8a6ef36a..fd3994f2f 100644 --- a/examples/AndroidMath/MemoryManager.h +++ b/examples/AndroidMath/MemoryManager.h @@ -5,7 +5,7 @@ #include /** - * Java simply memory manager. + * Java simple memory manager. */ template class MemoryManager { diff --git a/examples/EyeCare/EyeCare.upp b/examples/EyeCare/EyeCare.upp index 7eb06f97f..2b9d57c5f 100644 --- a/examples/EyeCare/EyeCare.upp +++ b/examples/EyeCare/EyeCare.upp @@ -1,4 +1,4 @@ -description "Tray application that reminds user to take care about his eyes"; +description "Tray application that reminds user to take care about his eyes\377"; uses CtrlLib; diff --git a/examples/FnGraph/FnGraph.upp b/examples/FnGraph/FnGraph.upp new file mode 100644 index 000000000..9203013ee --- /dev/null +++ b/examples/FnGraph/FnGraph.upp @@ -0,0 +1,12 @@ +description "Drawing a graph of text expression\377"; + +uses + CtrlLib, + Painter; + +file + main.cpp; + +mainconfig + "" = "GUI"; + diff --git a/examples/FnGraph/init b/examples/FnGraph/init new file mode 100644 index 000000000..6e0c8d09b --- /dev/null +++ b/examples/FnGraph/init @@ -0,0 +1,5 @@ +#ifndef _FnGraph_icpp_init_stub +#define _FnGraph_icpp_init_stub +#include "CtrlLib/init" +#include "Painter/init" +#endif diff --git a/examples/FnGraph/main.cpp b/examples/FnGraph/main.cpp new file mode 100644 index 000000000..64e6f6b91 --- /dev/null +++ b/examples/FnGraph/main.cpp @@ -0,0 +1,171 @@ +#include +#include + +using namespace Upp; + +struct ExpressionEvaluator { + CParser p; // this will hold our lexical context + double x; // 'variable' + + double Factor(); + double Exponent(); + double Term(); + double Expression(); +}; + +double ExpressionEvaluator::Expression() +{ // resolve + - + double y = Term(); // at least one term + for(;;) + if(p.Char('+')) + y = y + Term(); // add another term + else + if(p.Char('-')) + y = y - Term(); // subtract another term + else + return x; // no more + - operators +} + +double ExpressionEvaluator::Term() +{ // resolve * / + double y = Exponent(); // at least one member + for(;;) + if(p.Char('*')) + y = y * Exponent(); // multiply by another member + else + if(p.Char('/')) + y = y / Exponent(); // divide by another member + else + return y; // no more * / operators +} + +double ExpressionEvaluator::Exponent() +{ // resolve power ^ + double y = Factor(); // at least one factor + for(;;) + if(p.Char('^')) + y = pow(y, Factor()); // power by another factor + else + return y; // no more power ^ operators +} + +double ExpressionEvaluator::Factor() +{ + if(p.Char('-')) // unary - + return -Factor(); + if(p.Id("abs")) // some functions... + return fabs(Factor()); + if(p.Id("sqrt")) + return sqrt(Factor()); + if(p.Id("ln")) + return log(Factor()); + if(p.Id("log")) + return log10(Factor()); + if(p.Id("log2")) + return log2(Factor()); + if(p.Id("sin")) + return sin(Factor()); + if(p.Id("cos")) + return cos(Factor()); + if(p.Id("tan")) + return tan(Factor()); + if(p.Id("asin")) + return asin(Factor()); + if(p.Id("acos")) + return acos(Factor()); + if(p.Id("atan")) + return atan(Factor()); + if(p.Id("x")) // our variable + return x; + if(p.Id("e")) // e constant + return M_E; + if(p.Id("pi")) // pi constant + return M_PI; + if(p.Char('(')) { // resolve parenthesis - recurse back to Sum (+ - operators) + double y = Expression(); + p.PassChar(')'); // make sure there is closing parenthesis + return y; + } + return p.ReadDouble(); // last possibility is that we are at number... +} + +double Evaluate(const char *s, double x) +{ // evaluate expression for given variable, return Null on any failure or out-of-bounds result (NaN) + ExpressionEvaluator v; + v.x = x; + v.p.Set(s); + try { + double y = v.Expression(); + return y >= -1e200 && y < 1e200 ? y : Null; + } + catch(CParser::Error) {} + return Null; +} + +struct FnGraph : public TopWindow { + virtual void Paint(Draw& w); + + EditString expression; // function to display + + FnGraph(); +}; + +FnGraph::FnGraph() +{ + Title("Graph of a function"); + Add(expression.TopPos(0).HSizePos()); // place widget to the top, horizontally fill the window + expression << [&] { Refresh(); }; // when expression changes, repaint the graph + Sizeable().Zoomable(); // make the window resizable +} + +void FnGraph::Paint(Draw& w_) +{ + Size sz = GetSize(); + DrawPainter w(w_, sz); // Use Painter for smooth sw rendering + w.Clear(White()); // clear the background + int ecy = expression.GetSize().cy; // query the height of widget + w.Offset(0, ecy); // move coordinates out of widget + sz.cy -= ecy; // and reduce the size + if(sz.cy < 1) // if too small, do nothing (avoid div by zero) + return; + sz = sz / 2 * 2 - 1; // this trick will force axes to .5, results in sharper AA rendering + double pixels_per_unit = sz.cy / 9; // we want to display y range -4.5 .. 4.5 + double xaxis = sz.cy / 2.0; // vertical position of x axis + double yaxis = sz.cx / 2.0; // horizontal position of y axis + w.Move(0, xaxis).Line(sz.cx, xaxis).Stroke(1, Blue()); // draw x axis + w.Move(yaxis, 0).Line(yaxis, sz.cy).Stroke(1, Blue()); // draw y axis + Font font = Serif(15); + if(pixels_per_unit > 20) // if big enough, paint some axis markers and numbers... + for(int i = 1; i < 2 * sz.cx / pixels_per_unit; i++) + for(int sgn = -1; sgn < 2; sgn += 2) { + String n = AsString(sgn * i); + Size tsz = GetTextSize(n, font); + + double x = yaxis + sgn * i * pixels_per_unit; + w.Move(x, xaxis - 5).Line(x, xaxis + 5).Stroke(1, Blue()); + w.Text(int(x - tsz.cx / 2.0), int(xaxis + 6), n, font).Fill(Blue()); + + double y = xaxis - sgn * i * pixels_per_unit; + w.Move(yaxis - 5, y).Line(yaxis + 5, y).Stroke(1, Blue()); + w.Text(int(yaxis + 6), int(y - tsz.cy / 2.0), n, font).Fill(Blue()); + } + double y0 = Null; // store previous value + for(int i = 0; i < sz.cx; i++) { // now iterate through all x pointes and draw the graph + double x = (i - sz.cx / 2.0) / pixels_per_unit; + double y = Evaluate(~~expression, x); + if(!IsNull(y)) { + double gy = sz.cy / 2.0 - y * pixels_per_unit; + if(IsNull(y0)) // previous value was defined + w.Move(i, gy); + else + w.Line(i, gy); + } + y0 = y; + } + w.Stroke(1, Black()); // finally paint the graph line +} + +GUI_APP_MAIN +{ + FnGraph().Run(); +} diff --git a/examples/UWord/UWord.upp b/examples/UWord/UWord.upp index 81d7e75fe..2609aceeb 100644 --- a/examples/UWord/UWord.upp +++ b/examples/UWord/UWord.upp @@ -11,6 +11,5 @@ file UWord.iml; mainconfig - "" = "GUI", - "" = "GUI .NOGTK"; + "" = "GUI";