mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
755 lines
16 KiB
C++
755 lines
16 KiB
C++
#include "GeoFun.h"
|
|
|
|
using namespace Upp;
|
|
|
|
#define IMAGECLASS GFImg
|
|
#define IMAGEFILE <GeoFun/GeoFun.iml>
|
|
#include <Draw/iml_source.h>
|
|
|
|
// When idraw = 1 it will create image at actual size based on radius values
|
|
// Else image created to screen window diaplay size
|
|
template <class T>
|
|
void DrawCanvas::DoPaint0(T& sw, int idraw)
|
|
{
|
|
double x1, y1;
|
|
int cnt1, cnt2;
|
|
int RunTo;
|
|
|
|
Sizef sz;
|
|
|
|
if(idraw == 1) {
|
|
sz = Sizef(2 * Radius1 + 20, 2 * Radius1 + 20);
|
|
}
|
|
|
|
else {
|
|
sz = GetSize();
|
|
}
|
|
|
|
sw.Clear(White());
|
|
|
|
x1 = sz.cx / 2;
|
|
y1 = sz.cy / 2;
|
|
|
|
// Show color fill. Draw bacground circle with color
|
|
|
|
if(ColorFill) {
|
|
if(ShowGradient) {
|
|
sw.Ellipse(x1, y1, Radius1, Radius1).Fill(x1, y1, fcolorB1, Radius1, fcolorB2);
|
|
}
|
|
|
|
else {
|
|
sw.Ellipse(x1, y1, Radius1, Radius1).Fill(fcolorB1);
|
|
}
|
|
}
|
|
|
|
cnt1 = data.GetCount();
|
|
|
|
for(int i = 0; i < data.GetCount(); i++) {
|
|
Vector<Pointf>& p = data[i].point;
|
|
sw.Move(x1 + p[0].x, y1 + p[0].y);
|
|
|
|
cnt2 = p.GetCount();
|
|
|
|
// If animation flag set do incremental display of curve
|
|
// elase show all curve points.
|
|
|
|
RunTo = ShowAnimation ? ShowTo : cnt2;
|
|
|
|
if(RunTo > cnt2)
|
|
RunTo = cnt2;
|
|
|
|
for(int j = 1; j < RunTo; j++)
|
|
sw.Line(x1 + p[j].x, y1 + p[j].y);
|
|
|
|
sw.Stroke(data[i].penwidth, data[i].lcolor);
|
|
|
|
sw.EvenOdd(true);
|
|
|
|
if(ColorFill) {
|
|
if(ShowGradient) {
|
|
sw.Fill(x1, y1, data[i].fcolorM1, Radius1, data[i].fcolorM2, GRADIENT_REFLECT);
|
|
}
|
|
|
|
else {
|
|
sw.Fill(data[i].fcolorM1);
|
|
}
|
|
}
|
|
|
|
// Show if option animation set
|
|
|
|
if(ShowAnimation) {
|
|
sw.BeginOnPath(1.0);
|
|
sw.DrawImage(0, -GFImg::Bee().GetHeight() / 2, GFImg::Bee());
|
|
sw.End();
|
|
|
|
sw.Ellipse(x1, y1, BaseR, BaseR).Stroke(3, Blue());
|
|
sw.Ellipse(x1 + data[i].CenR[RunTo - 2].x, y1 + data[i].CenR[RunTo - 2].y, RollR,
|
|
RollR)
|
|
.Stroke(3, LtBlue());
|
|
|
|
sw.Move(x1, y1);
|
|
sw.Line(x1 + data[i].CenR[RunTo - 2].x, y1 + data[i].CenR[RunTo - 2].y);
|
|
sw.Line(x1 + data[i].point[RunTo - 2].x, y1 + data[i].point[RunTo - 2].y);
|
|
sw.Stroke(3, Red());
|
|
ColorFill = false; // this is required to stop colorfill if other options are
|
|
// changed during animation
|
|
}
|
|
}
|
|
}
|
|
|
|
DrawCanvas::DrawCanvas() {}
|
|
|
|
// at present this function is redundant but kept here to improve printing in future
|
|
void DrawCanvas::DoPaint(Painter& sw)
|
|
{
|
|
bool painting = false;
|
|
|
|
if(painting) {
|
|
PaintingPainter h(4000, 4000);
|
|
DoPaint0(h, 0);
|
|
sw.Paint(h);
|
|
}
|
|
|
|
else
|
|
|
|
DoPaint0(sw, 0);
|
|
}
|
|
|
|
void DrawCanvas::Paint(Draw& drw)
|
|
{
|
|
Size sz = GetSize();
|
|
ImageBuffer ib(sz);
|
|
BufferPainter sw(ib);
|
|
|
|
bool transparent = false;
|
|
|
|
DoPaint(sw);
|
|
drw.DrawImage(0, 0, ib);
|
|
}
|
|
|
|
Image GeoFun::GetImage()
|
|
{
|
|
Size sz = Size(int(dc1.Radius1 * 2 + 20), int(dc1.Radius1 * 2 + 20));
|
|
ImageBuffer ib(sz);
|
|
BufferPainter bp(ib, MODE_ANTIALIASED);
|
|
dc1.DoPaint0(bp, 1);
|
|
|
|
return ib;
|
|
}
|
|
|
|
void GeoFun::SaveToImageFile(String fileName)
|
|
{
|
|
GuiLock __;
|
|
|
|
if(IsNull(fileName)) {
|
|
FileSel fs;
|
|
|
|
fs.Type("PNG file", "*.png");
|
|
fs.Type("JPEG file", "*.jpg");
|
|
|
|
if(!fs.ExecuteSaveAs(t_("Saving plot to PNG or JPEG file"))) {
|
|
Exclamation(t_("Plot has not been saved"));
|
|
return;
|
|
}
|
|
|
|
fileName = fs;
|
|
}
|
|
|
|
if(GetFileExt(fileName) == ".png") {
|
|
PNGEncoder encoder;
|
|
encoder.SaveFile(fileName, GetImage());
|
|
}
|
|
|
|
else if(GetFileExt(fileName) == ".jpg") {
|
|
JPGEncoder encoder(90);
|
|
encoder.SaveFile(fileName, GetImage());
|
|
}
|
|
|
|
else
|
|
Exclamation(Format(t_("File format \"%s\" not found"), GetFileExt(fileName)));
|
|
}
|
|
|
|
void GeoFun::SaveToAutoCadScript(String fileName)
|
|
{
|
|
if(IsNull(fileName)) {
|
|
FileSel fs;
|
|
|
|
fs.Type("SCR file", "*.scr");
|
|
|
|
if(!fs.ExecuteSaveAs(t_("Saving plot to Polyline -- AutoCAD Script "))) {
|
|
Exclamation(t_("Plot has not been saved"));
|
|
return;
|
|
}
|
|
|
|
fileName = fs;
|
|
}
|
|
|
|
if(GetFileExt(fileName) == ".scr") {
|
|
|
|
String sScr;
|
|
|
|
for(int i = 0; i < dc1.data.GetCount(); i++) {
|
|
sScr << "PLINE\n";
|
|
Vector<Pointf>& p = dc1.data[i].point;
|
|
|
|
for(int j = 0; j < p.GetCount(); j++)
|
|
sScr << p[j].x << "," << p[j].y << "\n";
|
|
|
|
sScr << "\nZ\nE\n";
|
|
}
|
|
|
|
FileOut fo;
|
|
|
|
fo.Open(fileName);
|
|
fo.Put(sScr);
|
|
fo.Close();
|
|
}
|
|
}
|
|
|
|
void GeoFun::SaveToSVG(String fileName)
|
|
{
|
|
if(IsNull(fileName)) {
|
|
FileSel fs;
|
|
|
|
fs.Type("SVG file", "*.svg");
|
|
|
|
if(!fs.ExecuteSaveAs(t_("Saving as SVG file "))) {
|
|
Exclamation(t_("SVG has not been saved"));
|
|
return;
|
|
}
|
|
|
|
fileName = fs;
|
|
}
|
|
|
|
if(GetFileExt(fileName) == ".svg") {
|
|
String sXML;
|
|
|
|
sXML.Clear();
|
|
|
|
sXML << "<?xml version=\"1.0\" standalone=\"no\"?>";
|
|
sXML << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" ";
|
|
sXML << "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">";
|
|
sXML << "<svg width=\"100%\" height=\"100%\" version=\"1.1\" ";
|
|
sXML << "xmlns=\"http://www.w3.org/2000/svg\"> \n \n";
|
|
|
|
for(int i = 0; i < dc1.data.GetCount(); i++) {
|
|
sXML << "\n<polygon points=\" ";
|
|
Vector<Pointf>& p = dc1.data[i].point;
|
|
|
|
for(int j = 0; j < p.GetCount(); j++)
|
|
sXML << Format("%0.4f", p[j].x) << "," << Format("%0.4f", p[j].y) << " ";
|
|
|
|
sXML << "\" style=\"fill:none;stroke:#00C000;stroke-width:0.4\" />\n";
|
|
}
|
|
|
|
sXML << "</svg>\n";
|
|
|
|
FileOut fo;
|
|
fo.Open(fileName);
|
|
fo.Put(sXML);
|
|
fo.Close();
|
|
}
|
|
}
|
|
|
|
void GeoFun::Print()
|
|
{
|
|
Report r;
|
|
String sQtf;
|
|
|
|
r.SetPageSize(4400, 4400);
|
|
|
|
Size sz = Size(4200, 4200);
|
|
Image im = GetImage();
|
|
|
|
qtfim = CreatePNGObject(im, Size(600, 600), sz);
|
|
|
|
sQtf << "[s0;= ";
|
|
sQtf << qtfim << " ]";
|
|
|
|
r << sQtf;
|
|
|
|
Perform(r);
|
|
}
|
|
|
|
// This function calculates curve data points for display
|
|
void GeoFun::PrepareData()
|
|
{
|
|
int p, q, pw;
|
|
|
|
double a, b, h;
|
|
double x, y;
|
|
double Period, step, t;
|
|
|
|
step = 1.0; // value in deg
|
|
|
|
int q1 = InputPane.edValP;
|
|
|
|
if(q1 > 0) {
|
|
p = InputPane.edValP;
|
|
}
|
|
|
|
else {
|
|
p = 1;
|
|
InputPane.edValP.SetData(p);
|
|
}
|
|
|
|
q1 = InputPane.edValQ;
|
|
|
|
if(q1 > 0) {
|
|
q = InputPane.edValQ;
|
|
}
|
|
|
|
else {
|
|
q = 1;
|
|
InputPane.edValQ.SetData(q);
|
|
}
|
|
|
|
q1 = InputPane.edPenWidth;
|
|
|
|
if(q1 > 0) {
|
|
pw = InputPane.edPenWidth;
|
|
}
|
|
|
|
else {
|
|
pw = 1;
|
|
InputPane.edPenWidth.SetData(pw);
|
|
}
|
|
|
|
Period = 2 * M_PI * p;
|
|
|
|
int iCrv = ~InputPane.CurveType;
|
|
|
|
if((iCrv == 1) || (iCrv == 3)) {
|
|
p = -p;
|
|
}
|
|
|
|
double tmp = InputPane.edBaseCircleRad;
|
|
|
|
if(tmp < 10) {
|
|
a = 10;
|
|
InputPane.edBaseCircleRad.SetData(a);
|
|
}
|
|
|
|
else {
|
|
a = InputPane.edBaseCircleRad;
|
|
}
|
|
|
|
b = (double)p * a / (double)q;
|
|
|
|
dc1.BaseR = a;
|
|
dc1.RollR = fabs(b);
|
|
|
|
if(iCrv < 2) {
|
|
h = fabs(b);
|
|
}
|
|
|
|
else {
|
|
tmp = InputPane.edArmLength;
|
|
|
|
if(tmp < 0) {
|
|
h = 0;
|
|
InputPane.edArmLength.SetData(h);
|
|
}
|
|
|
|
else {
|
|
h = InputPane.edArmLength;
|
|
}
|
|
}
|
|
|
|
dc1.Radius1 = fabs(a + b) + h;
|
|
|
|
InputPane.RollingRad = "Rolling Radius : " + Format("%0.2f", b);
|
|
|
|
dc1.Zoomed = InputPane.optZoom.GetData();
|
|
|
|
if(dc1.Zoomed) {
|
|
Size sz = dc1.GetSize();
|
|
double dmax = sz.cx;
|
|
|
|
if(sz.cy < dmax)
|
|
dmax = sz.cy;
|
|
|
|
dmax -= 10;
|
|
|
|
double zScale = fabs(dmax / (2 * dc1.Radius1));
|
|
|
|
a = a * zScale;
|
|
|
|
h = h * zScale;
|
|
|
|
b = b * zScale;
|
|
|
|
dc1.BaseR = a;
|
|
|
|
dc1.RollR = fabs(b);
|
|
|
|
dc1.Radius1 = fabs(a + b) + h;
|
|
}
|
|
|
|
dc1.data.Clear();
|
|
|
|
dc1.data.Add();
|
|
dc1.data[0].point.Clear();
|
|
dc1.data[0].CenR.Clear();
|
|
dc1.data[0].lcolor = ~InputPane.LineColor;
|
|
dc1.data[0].fcolorM1 = ~InputPane.FillColorM1;
|
|
dc1.data[0].fcolorM2 = ~InputPane.FillColorM2;
|
|
dc1.data[0].penwidth = pw;
|
|
|
|
dc1.fcolorB1 = ~InputPane.FillColorB1;
|
|
dc1.fcolorB2 = ~InputPane.FillColorB2;
|
|
|
|
dc1.ShowGradient = ~InputPane.optGradient;
|
|
dc1.ColorFill = ~InputPane.optColorFill;
|
|
|
|
int NumSteps = abs((int)(2.0 * (double)p * 180.0 / step)) + 1;
|
|
|
|
for(int i = 0; i < NumSteps; i++) {
|
|
t = (double)i / (double)NumSteps * Period;
|
|
x = (a + b) * cos(t) + h * cos(((a + b) / b) * t);
|
|
y = (a + b) * sin(t) + h * sin(((a + b) / b) * t);
|
|
|
|
Pointf p1;
|
|
p1.Clear();
|
|
p1.x = x;
|
|
p1.y = y;
|
|
dc1.data[0].point.Add(p1);
|
|
|
|
p1.Clear();
|
|
x = (a + b) * cos(t);
|
|
y = (a + b) * sin(t);
|
|
p1.x = x;
|
|
p1.y = y;
|
|
dc1.data[0].CenR.Add(p1);
|
|
}
|
|
|
|
Pointf p1;
|
|
|
|
p1.x = dc1.data[0].point[0].x;
|
|
p1.y = dc1.data[0].point[0].y;
|
|
dc1.data[0].point.Add(p1);
|
|
|
|
dc1.Refresh();
|
|
}
|
|
|
|
void GeoFun::ShowAnimated()
|
|
{
|
|
int MaxCnt = dc1.data[0].point.GetCount();
|
|
|
|
if(dc1.ShowAnimation) {
|
|
if(dc1.ShowTo < MaxCnt) {
|
|
dc1.Refresh();
|
|
dc1.ShowTo += dc1.AnimSpeed;
|
|
}
|
|
|
|
else {
|
|
dc1.ShowAnimation = false;
|
|
}
|
|
}
|
|
|
|
else {
|
|
Animate.Kill();
|
|
PrepareData();
|
|
}
|
|
}
|
|
|
|
void GeoFun::SetAnimation()
|
|
{
|
|
dc1.AnimSpeed = InputPane.edAnimSpeed.GetData();
|
|
dc1.ShowTo = 5;
|
|
|
|
dc1.ShowAnimation = dc1.ShowAnimation ? false : true;
|
|
dc1.ColorFill = false;
|
|
|
|
if(dc1.ShowAnimation) {
|
|
InputPane.btnShowAnimation.SetLabel("Stop Animation");
|
|
}
|
|
|
|
else {
|
|
InputPane.btnShowAnimation.SetLabel("Start Animation");
|
|
}
|
|
|
|
Animate.KillSet(-50, [=] { ShowAnimated(); });
|
|
}
|
|
|
|
void GeoFun::FirstDraw()
|
|
{
|
|
First = false;
|
|
PrepareData();
|
|
|
|
DUMP("First Draw");
|
|
}
|
|
|
|
void GeoFun::Serialize(Stream& s)
|
|
{
|
|
s % InputPane.edArmLength % InputPane.edBaseCircleRad % InputPane.edPenWidth
|
|
|
|
% InputPane.edValP % InputPane.edValQ
|
|
|
|
% InputPane.LineColor
|
|
|
|
% InputPane.FillColorM1 % InputPane.FillColorM2 % InputPane.FillColorB1 %
|
|
InputPane.FillColorB2
|
|
|
|
% InputPane.optGradient % InputPane.optColorFill % InputPane.CurveType %
|
|
InputPane.optZoom
|
|
|
|
% InputPane.edAnimSpeed;
|
|
|
|
SerializePlacement(s);
|
|
}
|
|
|
|
// Using layout to redraw on windows resize
|
|
void GeoFun::Layout()
|
|
{
|
|
if(!First) {
|
|
PrepareData();
|
|
}
|
|
|
|
TopWindow::Layout();
|
|
}
|
|
|
|
void GeoFun::About()
|
|
{
|
|
WithAboutLayout<TopWindow> dlg;
|
|
dlg.AboutText = GetTopic("topic://GeoFun/app/About$en-us").text;
|
|
CtrlLayoutOK(dlg, "About");
|
|
dlg.CenterScreen();
|
|
dlg.Run();
|
|
}
|
|
|
|
void GeoFun::Help()
|
|
{
|
|
HelpWindow helpme;
|
|
helpme.GoTo("topic://GeoFun/app/Help$en-us");
|
|
helpme.Execute();
|
|
}
|
|
|
|
void GeoFun::Exit() { Close(); }
|
|
|
|
void GeoFun::SetAnimationSpeed()
|
|
{
|
|
dc1.AnimSpeed = InputPane.edAnimSpeed.GetData();
|
|
|
|
if(dc1.AnimSpeed < 1)
|
|
dc1.AnimSpeed = 1;
|
|
|
|
if(dc1.AnimSpeed > 20)
|
|
dc1.AnimSpeed = 20;
|
|
|
|
InputPane.edAnimSpeed.SetData(dc1.AnimSpeed);
|
|
}
|
|
|
|
void GeoFun::OptionColorFill()
|
|
{
|
|
int i = InputPane.optColorFill.Get();
|
|
i = i ? 0 : 1;
|
|
InputPane.optColorFill.Set(i);
|
|
PrepareData();
|
|
}
|
|
|
|
void GeoFun::OptionGradient()
|
|
{
|
|
int i = InputPane.optGradient.Get();
|
|
i = i ? 0 : 1;
|
|
InputPane.optGradient.Set(i);
|
|
PrepareData();
|
|
}
|
|
|
|
void GeoFun::OptionZoom()
|
|
{
|
|
int i = InputPane.optZoom.Get();
|
|
i = i ? 0 : 1;
|
|
InputPane.optZoom.Set(i);
|
|
PrepareData();
|
|
}
|
|
|
|
void GeoFun::SetCurveType(int CrvType)
|
|
{
|
|
InputPane.CurveType.SetData(CrvType);
|
|
SetCurveTypeMenu(CrvType);
|
|
}
|
|
|
|
void GeoFun::SetCurveTypeMenu(int CrvType)
|
|
{
|
|
EpiCyclo = HypoCyclo = EpiTroch = HypoTroch = false;
|
|
|
|
switch(CrvType) {
|
|
|
|
case 1:
|
|
HypoCyclo = true;
|
|
break;
|
|
|
|
case 2:
|
|
EpiTroch = true;
|
|
break;
|
|
|
|
case 3:
|
|
HypoTroch = true;
|
|
break;
|
|
|
|
default:
|
|
EpiCyclo = true;
|
|
}
|
|
|
|
PrepareData();
|
|
}
|
|
|
|
// Menu Functions
|
|
|
|
void GeoFun::SettingsMenu(Bar& bar)
|
|
{
|
|
bar.Add(t_("Color Fill"), [=] { OptionColorFill(); })
|
|
.Check(dc1.ColorFill)
|
|
.Help(t_("Change settings"));
|
|
bar.Add(t_("Gradient Fill"), [=] { OptionGradient(); })
|
|
.Check(dc1.ShowGradient)
|
|
.Help(t_("Change settings"));
|
|
bar.Add(t_("Zoom Fit"), [=] { OptionZoom(); })
|
|
.Check(dc1.Zoomed)
|
|
.Help(t_("Zoom fit to window area"));
|
|
}
|
|
|
|
void GeoFun::FileMenu(Bar& bar)
|
|
{
|
|
bar.Add(t_("Save Image"), CtrlImg::save_as(), [=] { SaveToImageFile(""); })
|
|
.Help(t_("Save Image as PNG or JPG"));
|
|
bar.Add(t_("Save AutoCAD Script"), CtrlImg::save(), [=] { SaveToAutoCadScript(""); })
|
|
.Help(t_("Save as AutoCAD Script (.scr) file"));
|
|
bar.Add(t_("Save as SVG"), CtrlImg::save(), [=] { SaveToSVG(""); })
|
|
.Help(t_("Save as Scalable vector graphics (.svg) file"));
|
|
bar.Separator();
|
|
bar.Add(t_("Print"), CtrlImg::print(), [=] { Print(); })
|
|
.Help(t_("Print the image , will fit to A4 page"));
|
|
bar.Separator();
|
|
bar.Add(t_("Exit"), [=] { Exit(); }).Help(t_("Exit the application"));
|
|
}
|
|
|
|
void GeoFun::CurvesMenu(Bar& bar)
|
|
{
|
|
bar.Add(t_("Epicycloid"), [=] { SetCurveType(0); })
|
|
.Help(t_("Plot Epicycloid curve"))
|
|
.Check(EpiCyclo);
|
|
bar.Add(t_("Hypocycloid"), [=] { SetCurveType(1); })
|
|
.Help(t_("Plot Hypocycloid curve"))
|
|
.Check(HypoCyclo);
|
|
bar.Add(t_("Epitrochoid"), [=] { SetCurveType(2); })
|
|
.Help(t_("Plot Epitrochoid curve"))
|
|
.Check(EpiTroch);
|
|
bar.Add(t_("Hypotrochoid"), [=] { SetCurveType(3); })
|
|
.Help(t_("Plot Hypotrochoid curve"))
|
|
.Check(HypoTroch);
|
|
bar.Separator();
|
|
bar.Add(t_("Animated Plot"), [=] { SetAnimation(); })
|
|
.Help(t_("Show animation of the curve drawing"))
|
|
.Check(AnimMn);
|
|
}
|
|
|
|
void GeoFun::MainMenu(Bar& bar)
|
|
{
|
|
bar.Sub(t_("File"), [=](Bar& bar) { FileMenu(bar); });
|
|
bar.Sub(t_("Curves"), [=](Bar& bar) { CurvesMenu(bar); });
|
|
bar.Sub(t_("Options"), [=](Bar& bar) { SettingsMenu(bar); });
|
|
bar.Sub(t_("Assist"), [=](Bar& bar) { HelpMenu(bar); });
|
|
}
|
|
|
|
void GeoFun::HelpMenu(Bar& bar)
|
|
{
|
|
bar.Add(t_("About"), [=] { About(); }).Help(t_("About GeoFun"));
|
|
bar.Separator();
|
|
bar.Add(t_("Help"), CtrlImg::help(), [=] { Help(); }).Help(t_("Help GeoFun"));
|
|
}
|
|
|
|
GeoFun::GeoFun()
|
|
{
|
|
CtrlLayout(*this, "GeoFun : Enjoy Geometric Curves");
|
|
|
|
Icon(GFImg::gficon());
|
|
|
|
CtrlLayout(InputPane);
|
|
|
|
Sizeable().Zoomable();
|
|
|
|
InputPane.btnImg << [=] { SaveToImageFile(""); };
|
|
InputPane.btnPrint << [=] { Print(); };
|
|
InputPane.btnShowAnimation << [=] { SetAnimation(); };
|
|
|
|
Add(dc1.HSizePosZ(5, 160).VSizePosZ(25, 5));
|
|
Add(InputPane.RightPosZ(5, 150).VSizePosZ(2, 5));
|
|
BackPaint();
|
|
|
|
dc1.data.Clear();
|
|
|
|
// Check config file available else set default data
|
|
if(!cfgAvailable) {
|
|
InputPane.edArmLength.SetData(112);
|
|
InputPane.edBaseCircleRad.SetData(145);
|
|
InputPane.edPenWidth.SetData(3);
|
|
InputPane.edValP.SetData(5);
|
|
InputPane.edValQ.SetData(12);
|
|
InputPane.edAnimSpeed.SetData(5);
|
|
|
|
InputPane.LineColor.SetData(Blue());
|
|
InputPane.FillColorM1.SetData(LtGreen());
|
|
InputPane.FillColorM2.SetData(Yellow());
|
|
InputPane.FillColorB1.SetData(Blue());
|
|
InputPane.FillColorB2.SetData(LtCyan());
|
|
|
|
InputPane.optGradient.Set(1);
|
|
InputPane.optColorFill.Set(1);
|
|
InputPane.CurveType.SetData(2);
|
|
}
|
|
|
|
InputPane.CurveType.WhenAction
|
|
<< [=] { SetCurveTypeMenu((int)InputPane.CurveType.GetData()); };
|
|
|
|
InputPane.optGradient.WhenAction << [=] { PrepareData(); };
|
|
InputPane.optColorFill.WhenAction << [=] { PrepareData(); };
|
|
|
|
InputPane.FillColorB1.WhenAction << [=] { PrepareData(); };
|
|
InputPane.FillColorB2.WhenAction << [=] { PrepareData(); };
|
|
InputPane.FillColorM1.WhenAction << [=] { PrepareData(); };
|
|
InputPane.FillColorM2.WhenAction << [=] { PrepareData(); };
|
|
InputPane.LineColor.WhenAction << [=] { PrepareData(); };
|
|
|
|
InputPane.edPenWidth.WhenAction << [=] { PrepareData(); };
|
|
InputPane.edValP.WhenAction << [=] { PrepareData(); };
|
|
InputPane.edValQ.WhenAction << [=] { PrepareData(); };
|
|
InputPane.edArmLength.WhenAction << [=] { PrepareData(); };
|
|
InputPane.edBaseCircleRad.WhenAction << [=] { PrepareData(); };
|
|
InputPane.edAnimSpeed.WhenAction << [=] { SetAnimationSpeed(); };
|
|
InputPane.optZoom.WhenAction << [=] { PrepareData(); };
|
|
|
|
// Set timercallback to do first painting with calculations
|
|
// You can not call this directly from constructor
|
|
SetTimeCallback(200, [=] { FirstDraw(); });
|
|
|
|
dc1.ShowTo = 5; // start point of animation.
|
|
|
|
menu.Set([=](Bar& bar) { MainMenu(bar); });
|
|
dc1.ShowAnimation = false;
|
|
}
|
|
|
|
GUI_APP_MAIN
|
|
{
|
|
GeoFun gf;
|
|
gf.First = true;
|
|
String cfgfile = ConfigFile();
|
|
|
|
if(FileExists(cfgfile)) {
|
|
cfgAvailable = true;
|
|
|
|
if(!LoadFromFile(gf, cfgfile)) {
|
|
cfgAvailable = false;
|
|
Exclamation("Error loading configuration file!");
|
|
}
|
|
}
|
|
|
|
else {
|
|
cfgAvailable = false;
|
|
}
|
|
|
|
gf.Run();
|
|
|
|
StoreToFile(gf);
|
|
}
|