1 /***************************************************************************
2  * window.cpp is part of Math Graphic Library
3  * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru>       *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU Lesser General Public License  as       *
7  *   published by the Free Software Foundation; either version 3 of the    *
8  *   License, or (at your option) any later version.                       *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU Lesser General Public     *
16  *   License along with this program; if not, write to the                 *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #include "mgl2/canvas_wnd.h"
21 //-----------------------------------------------------------------------------
mglCanvasWnd()22 mglCanvasWnd::mglCanvasWnd() : mglCanvas()
23 {
24 	Setup();	LoadFunc=0;	FuncPar=0;	DrawFunc=0;	ClickFunc=0;
25 	GG = 0;		NumFig = 0;	CurFig=-1;	PropFunc=0;	PropPar=0;
26 #if MGL_HAVE_PTHR_WIDGET
27 	mutex=0;
28 #endif
29 }
30 //-----------------------------------------------------------------------------
~mglCanvasWnd()31 mglCanvasWnd::~mglCanvasWnd()	{	if(GG) free(GG);	}
32 //-----------------------------------------------------------------------------
SetCurFig(int c)33 void mglCanvasWnd::SetCurFig(int c)
34 {
35 	CurFig=c;
36 	if(get(MGL_VECT_FRAME) && c>=0 && c<(long)DrwDat.size() && DrawFunc)
37 		GetFrame(c);
38 }
39 //-----------------------------------------------------------------------------
ResetFrames()40 void mglCanvasWnd::ResetFrames()
41 {
42 	if(GG)	free(GG);
43 	GG = 0;	NumFig = CurFig = 0;
44 	mglCanvas::ResetFrames();
45 }
46 //-----------------------------------------------------------------------------
SetSize(int w,int h,bool)47 void mglCanvasWnd::SetSize(int w,int h,bool)
48 {
49 	if(DrawFunc)	ResetFrames();
50 	mglCanvas::SetSize(w,h,false);
51 //	if(Wnd)	Wnd->size(w,h);
52 }
53 //-----------------------------------------------------------------------------
EndFrame()54 void mglCanvasWnd::EndFrame()
55 {
56 	CurFig = CurFrameId-1;
57 	if(!GG)
58 	{
59 		GG = (unsigned char *)malloc(3*Width*Height);
60 		NumFig = 1;		CurFig = 0;
61 	}
62 	else if(CurFig>NumFig-1)
63 	{
64 		GG = (unsigned char *)realloc(GG,3*(CurFig+1)*Width*Height);
65 		NumFig = CurFig+1;
66 	}
67 	mglCanvas::EndFrame();
68 	memcpy(GG + CurFig*Width*Height*3,G,3*Width*Height);
69 	CurFig++;
70 }
71 //-----------------------------------------------------------------------------
SetFrame(long i)72 void mglCanvasWnd::SetFrame(long i)
73 {
74 	mglCanvas::SetFrame(i);
75 	if(i>=0 && i<NumFig)	memcpy(GG + i*Width*Height*3,G,3*Width*Height);
76 }
77 //-----------------------------------------------------------------------------
DelFrame(long i)78 void mglCanvasWnd::DelFrame(long i)
79 {
80 	if(i<0 || i>=CurFrameId)	return;
81 	if(CurFig>=i)	CurFig--;
82 	long n = Width*Height*3;
83 	if(CurFrameId-i>1)	memmove(GG+i*n, GG+i*n+n, n*(CurFrameId-i-1));
84 	mglCanvas::DelFrame(i);
85 }
86 //-----------------------------------------------------------------------------
SetDrawFunc(int (* draw)(mglBase * gr,void * p),void * par,void (* reload)(void * p))87 void mglCanvasWnd::SetDrawFunc(int (*draw)(mglBase *gr, void *p), void *par, void (*reload)(void *p))
88 {
89 	if(draw)
90 	{
91 		ResetFrames();
92 		if(get(MGL_CLF_ON_UPD))	DefaultPlotParam();
93 		const std::string loc = setlocale(LC_NUMERIC, "C");
94 		// use frames for quickly redrawing while adding/changing primitives
95 		if(mgl_is_frames(this))	NewFrame();
96 
97 		int n = draw(this,par);
98 		if(n<NumFig && n>=0)	NumFig = n;
99 		DrawFunc = draw;		FuncPar = par;
100 		LoadFunc = reload;
101 
102 		if(mgl_is_frames(this))	EndFrame();
103 		if(n>=0)	SetCurFig(0);
104 		setlocale(LC_NUMERIC, loc.c_str());
105 	}
106 	else	LoadFunc = 0;
107 }
108 //-----------------------------------------------------------------------------
GetBits()109 const unsigned char *mglCanvasWnd::GetBits()
110 {
111 	const unsigned char *g = mglCanvas::GetBits();
112 	if(GG && NumFig>0 && CurFig<NumFig && CurFig>=0 && !get(MGL_VECT_FRAME))
113 		g = GG + CurFig*Width*Height*3;
114 	return g;
115 }
116 //-----------------------------------------------------------------------------
ReLoad()117 void mglCanvasWnd::ReLoad()
118 {
119 	if(LoadFunc)
120 	{
121 		LoadFunc(FuncPar);
122 		// update number of slides
123 		ResetFrames();
124 		const std::string loc = setlocale(LC_NUMERIC, "C");
125 		// use frames for quickly redrawing while adding/changing primitives
126 		if(mgl_is_frames(this))	NewFrame();
127 
128 		int n = DrawFunc ? DrawFunc(this,FuncPar) : 0;
129 		if(n<NumFig && n>=0)	NumFig = n;
130 
131 		if(mgl_is_frames(this))	EndFrame();
132 		setlocale(LC_NUMERIC, loc.c_str());
133 		Update();
134 	}
135 }
136 //-----------------------------------------------------------------------------
mgl_prop_func(char id,const char * val,void * p)137 void MGL_EXPORT mgl_prop_func(char id, const char *val, void *p)
138 {	mglCanvasWnd *g = (mglCanvasWnd *)(p);	if(g)	g->SetParam(id, val);	}
mgl_wnd_make_dialog(HMGL gr,const char * ids,char const * const * args,const char * title)139 void MGL_EXPORT mgl_wnd_make_dialog(HMGL gr, const char *ids, char const * const *args, const char *title)
140 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->MakeDialog(ids, args, title);	}
mgl_wnd_set_func(HMGL gr,int (* draw)(HMGL gr,void * p),void * par,void (* reload)(void * p))141 void MGL_EXPORT mgl_wnd_set_func(HMGL gr, int (*draw)(HMGL gr, void *p), void *par, void (*reload)(void *p))
142 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->SetDrawFunc(draw, par, reload);	}
mgl_wnd_set_prop(HMGL gr,void (* prop)(char id,const char * val,void * p),void * par)143 void MGL_EXPORT mgl_wnd_set_prop(HMGL gr, void (*prop)(char id, const char *val, void *p), void *par)
144 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->SetPropFunc(prop, par);	}
mgl_wnd_toggle_alpha(HMGL gr)145 void MGL_EXPORT mgl_wnd_toggle_alpha(HMGL gr)
146 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->ToggleAlpha();	}
mgl_wnd_toggle_light(HMGL gr)147 void MGL_EXPORT mgl_wnd_toggle_light(HMGL gr)
148 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->ToggleLight();	}
mgl_wnd_toggle_zoom(HMGL gr)149 void MGL_EXPORT mgl_wnd_toggle_zoom(HMGL gr)
150 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->ToggleZoom();	}
mgl_wnd_toggle_rotate(HMGL gr)151 void MGL_EXPORT mgl_wnd_toggle_rotate(HMGL gr)
152 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->ToggleRotate();	}
mgl_wnd_toggle_no(HMGL gr)153 void MGL_EXPORT mgl_wnd_toggle_no(HMGL gr)
154 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->ToggleNo();	}
mgl_wnd_update(HMGL gr)155 void MGL_EXPORT mgl_wnd_update(HMGL gr)
156 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->Update();	}
mgl_wnd_reload(HMGL gr)157 void MGL_EXPORT mgl_wnd_reload(HMGL gr)
158 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->ReLoad();	}
mgl_wnd_adjust(HMGL gr)159 void MGL_EXPORT mgl_wnd_adjust(HMGL gr)
160 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->Adjust();	}
mgl_wnd_next_frame(HMGL gr)161 void MGL_EXPORT mgl_wnd_next_frame(HMGL gr)
162 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->NextFrame();	}
mgl_wnd_prev_frame(HMGL gr)163 void MGL_EXPORT mgl_wnd_prev_frame(HMGL gr)
164 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->PrevFrame();	}
mgl_wnd_animation(HMGL gr)165 void MGL_EXPORT mgl_wnd_animation(HMGL gr)
166 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->Animation();	}
mgl_setup_window(HMGL gr,int clf_upd,int showpos)167 void MGL_EXPORT mgl_setup_window(HMGL gr, int clf_upd, int showpos)
168 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->Setup(clf_upd, showpos);	}
mgl_set_click_func(HMGL gr,void (* func)(void * p))169 void MGL_EXPORT mgl_set_click_func(HMGL gr, void (*func)(void *p))
170 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->ClickFunc = func;	}
mgl_get_last_mouse_pos(HMGL gr,mreal * x,mreal * y,mreal * z)171 void MGL_EXPORT mgl_get_last_mouse_pos(HMGL gr, mreal *x, mreal *y, mreal *z)
172 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);
173 	mglPoint p;	if(g)	p=g->GetMousePos();
174 	*x=p.x;	*y=p.y;	*z=p.z;	}
mgl_wnd_window(HMGL gr)175 MGL_EXPORT void *mgl_wnd_window(HMGL gr)
176 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	return g?g->Window():NULL;	}
mgl_wnd_widget(HMGL gr)177 MGL_EXPORT void *mgl_wnd_widget(HMGL gr)
178 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	return g?g->Widget():NULL;	}
179 /// Move window to given position
mgl_wnd_move(HMGL gr,int x,int y)180 void MGL_EXPORT mgl_wnd_move(HMGL gr, int x, int y)
181 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->WndMove(x,y);	}
mgl_wnd_move_(uintptr_t * gr,int * x,int * y)182 void MGL_EXPORT mgl_wnd_move_(uintptr_t *gr, int *x, int *y)
183 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));	if(g)	g->WndMove(*x,*y);	}
184 /// Change window sizes
mgl_wnd_size(HMGL gr,int w,int h)185 void MGL_EXPORT mgl_wnd_size(HMGL gr, int w, int h)
186 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);	if(g)	g->WndSize(w,h);	}
mgl_wnd_size_(uintptr_t * gr,int * w,int * h)187 void MGL_EXPORT mgl_wnd_size_(uintptr_t *gr, int *w, int *h)
188 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));	if(g)	g->WndSize(*w,*h);	}
189 //-----------------------------------------------------------------------------
mgl_wnd_toggle_alpha_(uintptr_t * gr)190 void MGL_EXPORT mgl_wnd_toggle_alpha_(uintptr_t *gr)
191 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
192 	if(g)	g->ToggleAlpha();	}
mgl_wnd_toggle_light_(uintptr_t * gr)193 void MGL_EXPORT mgl_wnd_toggle_light_(uintptr_t *gr)
194 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
195 	if(g)	g->ToggleLight();	}
mgl_wnd_toggle_zoom_(uintptr_t * gr)196 void MGL_EXPORT mgl_wnd_toggle_zoom_(uintptr_t *gr)
197 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
198 	if(g)	g->ToggleZoom();	}
mgl_wnd_toggle_rotate_(uintptr_t * gr)199 void MGL_EXPORT mgl_wnd_toggle_rotate_(uintptr_t *gr)
200 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
201 	if(g)	g->ToggleRotate();	}
mgl_wnd_toggle_no_(uintptr_t * gr)202 void MGL_EXPORT mgl_wnd_toggle_no_(uintptr_t *gr)
203 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
204 	if(g)	g->ToggleNo();	}
mgl_wnd_update_(uintptr_t * gr)205 void MGL_EXPORT mgl_wnd_update_(uintptr_t *gr)
206 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
207 	if(g)	g->Update();	}
mgl_wnd_reload_(uintptr_t * gr)208 void MGL_EXPORT mgl_wnd_reload_(uintptr_t *gr)
209 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
210 	if(g)	g->ReLoad();	}
mgl_wnd_adjust_(uintptr_t * gr)211 void MGL_EXPORT mgl_wnd_adjust_(uintptr_t *gr)
212 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
213 	if(g)	g->Adjust();	}
mgl_wnd_next_frame_(uintptr_t * gr)214 void MGL_EXPORT mgl_wnd_next_frame_(uintptr_t *gr)
215 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
216 	if(g)	g->NextFrame();	}
mgl_wnd_prev_frame_(uintptr_t * gr)217 void MGL_EXPORT mgl_wnd_prev_frame_(uintptr_t *gr)
218 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
219 	if(g)	g->PrevFrame();	}
mgl_wnd_animation_(uintptr_t * gr)220 void MGL_EXPORT mgl_wnd_animation_(uintptr_t *gr)
221 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
222 	if(g)	g->Animation();	}
mgl_setup_window_(uintptr_t * gr,int * clf_upd,int * showpos)223 void MGL_EXPORT mgl_setup_window_(uintptr_t *gr, int *clf_upd, int *showpos)
224 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
225 	if(g)	g->Setup(*clf_upd, *showpos);	}
mgl_get_last_mouse_pos_(uintptr_t * gr,mreal * x,mreal * y,mreal * z)226 void MGL_EXPORT mgl_get_last_mouse_pos_(uintptr_t *gr, mreal *x, mreal *y, mreal *z)
227 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>((HMGL)(*gr));
228 	mglPoint p;	if(g)	p=g->GetMousePos();
229 	*x=p.x;	*y=p.y;	*z=p.z;	}
230 //-----------------------------------------------------------------------------
231 #if MGL_HAVE_PTHR_WIDGET
mgl_wnd_set_mutex(HMGL gr,pthread_mutex_t * mutex)232 void MGL_EXPORT mgl_wnd_set_mutex(HMGL gr, pthread_mutex_t *mutex)
233 {	mglCanvasWnd *g = dynamic_cast<mglCanvasWnd *>(gr);
234 	if(g)	g->mutex = mutex;	}
235 #endif
236 //-----------------------------------------------------------------------------
237 //
238 //	mglDraw class handling
239 //
240 //-----------------------------------------------------------------------------
241 /*int mgl_draw_class(HMGL gr, void *p)	// so stupid way to save mglDraw class inheritance :(
242 {
243 	mglGraph g(gr);	mglWindow *w = (mglWindow *)p;
244 	return (w && w->dr) ? w->dr->Draw(&g) : 0;
245 }
246 void MGL_EXPORT mgl_reload_class(void *p)	// so stupid way to save mglDraw class inheritance :(
247 {	mglWindow *w = (mglWindow *)p;	if(w && w->dr)	w->dr->Reload();}
248 void MGL_EXPORT mgl_click_class(void *p)	// so stupid way to save mglDraw class inheritance :(
249 {	mglWindow *w = (mglWindow *)p;	if(w && w->dr)	w->dr->Click();	}*/
mgl_draw_class(HMGL gr,void * p)250 int MGL_EXPORT mgl_draw_class(HMGL gr, void *p)
251 {	mglGraph g(gr);	mglDraw *dr = (mglDraw *)p;	return dr?dr->Draw(&g):0;	}
mgl_reload_class(void * p)252 void MGL_EXPORT mgl_reload_class(void *p)
253 {	mglDraw *dr = (mglDraw *)p;	if(dr)	dr->Reload();	}
mgl_click_class(void * p)254 void MGL_EXPORT mgl_click_class(void *p)
255 {	mglDraw *dr = (mglDraw *)p;	if(dr)	dr->Click();		}
mgl_prop_class(char id,const char * val,void * p)256 void MGL_EXPORT mgl_prop_class(char id, const char *val, void *p)
257 {	mglDraw *dr = (mglDraw *)p;	if(dr)	dr->Param(id,val);	}
258 //-----------------------------------------------------------------------------
259 typedef int (*draw_func)(mglGraph *gr);
mgl_draw_graph(HMGL gr,void * p)260 int MGL_EXPORT mgl_draw_graph(HMGL gr, void *p)
261 {
262 	mglGraph g(gr);
263 	draw_func func = (draw_func)(p);
264 	return func ? func(&g) : 0;
265 }
266 //-----------------------------------------------------------------------------
mgl_draw_calc(void * p)267 MGL_EXPORT void *mgl_draw_calc(void *p)
268 {
269 #if MGL_HAVE_PTHR_WIDGET
270 	mglDraw *d = (mglDraw *)p;
271 	d->Calc();	d->running = false;
272 #endif
273 	return 0;
274 }
275 //-----------------------------------------------------------------------------
mgl_parse_comments(const wchar_t * text,double & a1,double & a2,double & da,std::vector<std::wstring> & anim,std::string & ids,std::vector<std::wstring> & par)276 void MGL_EXPORT mgl_parse_comments(const wchar_t *text, double &a1, double &a2, double &da, std::vector<std::wstring> &anim, std::string &ids, std::vector<std::wstring> &par)
277 {
278 	a1=0;	a2=0;	da=1;
279 	const wchar_t *str = wcsstr(text, L"##c");
280 	if(str)	// this is animation loop
281 	{
282 		int res=wscanf(str+3, "%lg%lg%lg", &a1, &a2, &da);
283 		da = res<3?1:da;
284 		if(res>2 && da*(a2-a1)>0)
285 		{
286 			for(double a=a1;da*(a2-a)>=0;a+=da)
287 			{
288 				wchar_t buf[128];	swprintf(buf,128,L"%g",a);
289 				anim.push_back(buf);
290 			}
291 			return;
292 		}
293 	}
294 	str = wcsstr(text, L"##a");
295 	while(str)
296 	{
297 		str += 3;
298 		while(*str>0 && *str<=' ' && *str!='\n')	str++;
299 		if(*str>' ')
300 		{
301 			size_t j=0;	while(str[j]>' ')	j++;
302 			std::wstring val(str,j);
303 			anim.push_back(val);
304 		}
305 		str = wcsstr(str, L"##a");
306 	}
307 	str = wcsstr(text, L"##d");	// custom dialog
308 	while(str)
309 	{
310 		str = wcschr(str,'$');
311 		if(str)
312 		{
313 			char id = str[1];	str += 2;
314 			while(*str>0 && *str<=' ' && *str!='\n')	str++;
315 			if(*str>' ')
316 			{
317 				long j=0;	while(str[j]!='\n')	j++;
318 				while(str[j-1]<=' ')	j--;
319 
320 				ids.push_back(id);
321 				std::wstring val(str,j);
322 				par.push_back(val);
323 			}
324 		}
325 		str = wcsstr(str, L"##d");
326 	}
327 }
328 //-----------------------------------------------------------------------------
mgl_parse_comments(const char * text,double & a1,double & a2,double & da,std::vector<std::string> & anim,std::string & ids,std::vector<std::string> & par)329 void MGL_EXPORT mgl_parse_comments(const char *text, double &a1, double &a2, double &da, std::vector<std::string> &anim, std::string &ids, std::vector<std::string> &par)
330 {
331 	a1=0;	a2=0;	da=1;
332 	const char *str = strstr(text, "##c");
333 	if(str)	// this is animation loop
334 	{
335 		int res=sscanf(str+3, "%lg%lg%lg", &a1, &a2, &da);
336 		da = res<3?1:da;
337 		if(res>2 && da*(a2-a1)>0)
338 		{
339 			for(double a=a1;da*(a2-a)>=0;a+=da)
340 			{
341 				char buf[128];	snprintf(buf,128,"%g",a);
342 				anim.push_back(buf);
343 			}
344 			return;
345 		}
346 	}
347 	str = strstr(text, "##a");
348 	while(str)
349 	{
350 		str += 3;
351 		while(*str>0 && *str<=' ' && *str!='\n')	str++;
352 		if(*str>' ')
353 		{
354 			size_t j=0;	while(str[j]>' ')	j++;
355 			std::string val(str,j);
356 			anim.push_back(val);
357 		}
358 		str = strstr(str, "##a");
359 	}
360 	str = strstr(text, "##d");	// custom dialog
361 	while(str)
362 	{
363 		str = strchr(str,'$');
364 		if(str)
365 		{
366 			char id = str[1];	str += 2;
367 			while(*str>0 && *str<=' ' && *str!='\n')	str++;
368 			if(*str>' ')
369 			{
370 				long j=0;	while(str[j]!='\n')	j++;
371 				while(str[j-1]<=' ')	j--;
372 
373 				ids.push_back(id);
374 				std::string val(str,j);
375 				par.push_back(val);
376 			}
377 		}
378 		str = strstr(str, "##d");
379 	}
380 }
381 //-----------------------------------------------------------------------------
mgl_parse_animation(const char * text,std::vector<std::string> & anim)382 void MGL_EXPORT mgl_parse_animation(const char *text, std::vector<std::string> &anim)
383 {
384 	std::string ids;
385 	std::vector<std::string> par;
386 	double a1, a2, da;
387 	mgl_parse_comments(text, a1, a2, da, anim, ids, par);
388 }
389 //-----------------------------------------------------------------------------
mgl_parse_animation(const wchar_t * text,std::vector<std::wstring> & anim)390 void MGL_EXPORT mgl_parse_animation(const wchar_t *text, std::vector<std::wstring> &anim)
391 {
392 	std::string ids;
393 	std::vector<std::wstring> par;
394 	double a1, a2, da;
395 	mgl_parse_comments(text, a1, a2, da, anim, ids, par);
396 }
397 //-----------------------------------------------------------------------------
398 #undef _GR_
399 #define _GR_	((mglCanvas *)(*gr))
mgl_wnd_set_delay(HMGL gr,double dt)400 void MGL_EXPORT mgl_wnd_set_delay(HMGL gr, double dt)
401 {	mglCanvas *g = dynamic_cast<mglCanvas *>(gr);	if(g)	g->SetDelay(dt);	}
mgl_wnd_get_delay(HMGL gr)402 double MGL_EXPORT_PURE mgl_wnd_get_delay(HMGL gr)
403 {	mglCanvas *g = dynamic_cast<mglCanvas *>(gr);	return g?g->GetDelay():0;	}
mgl_wnd_set_delay_(uintptr_t * gr,mreal * dt)404 void MGL_EXPORT mgl_wnd_set_delay_(uintptr_t *gr, mreal *dt)	{	_GR_->SetDelay(*dt);	}
mgl_wnd_get_delay_(uintptr_t * gr)405 double MGL_EXPORT_PURE mgl_wnd_get_delay_(uintptr_t *gr)	{	return _GR_->GetDelay();	}
406 //-----------------------------------------------------------------------------
407 MGL_EXPORT const char *mgl_hints[] = {
408 	_("You can shift axis range by pressing middle button and moving mouse. Also, you can zoom in/out axis range by using mouse wheel."),
409 	_("You can rotate/shift/zoom whole plot by mouse. Just press 'Rotate' toolbutton, click image and hold a mouse button: left button for rotation, right button for zoom/perspective, middle button for shift."),
410 	_("You may quickly draw the data from file. Just use: mgllab 'filename.dat' in command line."),
411 	_("You can copy the current image to clipboard by pressing Ctrl-Shift-C. Later you can paste it directly into yours document or presentation."),
412 	_("You can export image into a set of format (EPS, SVG, PNG, JPEG) by pressing right mouse button inside image and selecting 'Export as ...'."),
413 	_("You can setup colors for script highlighting in Property dialog. Just select menu item 'Settings/Properties'."),
414 	_("You can save the parameter of animation inside MGL script by using comment started from '##a ' or '##c ' for loops."),
415 	_("New drawing never clears things drawn already. For example, you can make a surface with contour lines by calling commands 'surf' and 'cont' one after another (in any order). "),
416 	_("You can put several plots in the same image by help of commands 'subplot' or 'inplot'."),
417 	_("All indexes (of data arrays, subplots and so on) are always start from 0."),
418 	_("You can edit MGL file in any text editor. Also you can run it in console by help of commands: mglconv, mglview."),
419 	_("You can use command 'once on|off' for marking the block which should be executed only once. For example, this can be the block of large data reading/creating/handling. Press F9 (or menu item 'Graphics/Reload') to re-execute this block."),
420 	_("You can use command 'stop' for terminating script parsing. It is useful if you don't want to execute a part of script."),
421 	_("You can type arbitrary expression as input argument for data or number. In last case (for numbers), the first value of data array is used."),
422 	_("There is powerful calculator with a lot of special functions. You can use buttons or keyboard to type the expression. Also you can use existed variables in the expression."),
423 	_("The calculator can help you to put complex expression in the script. Just type the expression (which may depend on coordinates x,y,z and so on) and put it into the script."),
424 	_("You can easily insert file or folder names, last fitted formula or numerical value of selection by using menu Edit|Insert."),
425 	_("The special dialog (Edit|Insert|New Command) help you select the command, fill its arguments and put it into the script."),
426 	_("You can put several plotting commands in the same line or in separate function, for highlighting all of them simultaneously."),
427 	_("You can concatenation of strings and numbers using `,` with out spaces (for example, `'max(u)=',u.max,' a.u.'` or `'u=',!(1+i2)` for complex numbers). Also you can get n-th symbol of the string using `[]` (for example, `'abc'[1]` will give 'b'), or add a value to the last character of the string using `+` (for example, `'abc'+3` will give 'abf'), or use it all together."),
428 	NULL
429 };
430 //-----------------------------------------------------------------------------
431