1 /* table.cpp is part of UDAV
2 * Copyright (C) 2007-2014 Alexey Balakin <mathgl.abalakin@gmail.ru>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17 #include <FL/Fl_Spinner.H>
18 #include <FL/Fl_Output.H>
19 #include <FL/Fl_Float_Input.H>
20 #include <FL/Fl_Value_Input.H>
21 #include <FL/Fl_Round_Button.H>
22 #include "mgllab.h"
23
24 //-----------------------------------------------------------------------------
addto_cb(Fl_Widget *,void * v)25 void addto_cb(Fl_Widget*, void*v)
26 {
27 TableWindow* e = (TableWindow*)v;
28 const char *s = fl_input(_("Enter number for addition to data values"),0);
29 HMDT d = dynamic_cast<HMDT>(e->var);
30 if(d && s) { mgl_data_add_num(d, atof(s)); e->refresh(); }
31 HADT c = dynamic_cast<HADT>(e->var);
32 if(c && s) { mgl_datac_add_num(c, mgl_atoc(s,true)); e->refresh(); }
33 }
34 //-----------------------------------------------------------------------------
subto_cb(Fl_Widget *,void * v)35 void subto_cb(Fl_Widget*, void*v)
36 {
37 TableWindow* e = (TableWindow*)v;
38 const char *s = fl_input(_("Enter number for subtraction from data values"),0);
39 HMDT d = dynamic_cast<HMDT>(e->var);
40 if(d && s) { mgl_data_sub_num(d, atof(s)); e->refresh(); }
41 HADT c = dynamic_cast<HADT>(e->var);
42 if(c && s) { mgl_datac_sub_num(c, mgl_atoc(s,true)); e->refresh(); }
43 }
44 //-----------------------------------------------------------------------------
multo_cb(Fl_Widget *,void * v)45 void multo_cb(Fl_Widget*, void*v)
46 {
47 TableWindow* e = (TableWindow*)v;
48 const char *s = fl_input(_("Enter number for multiplication of data values"),0);
49 HMDT d = dynamic_cast<HMDT>(e->var);
50 if(d && s) { mgl_data_mul_num(d, atof(s)); e->refresh(); }
51 HADT c = dynamic_cast<HADT>(e->var);
52 if(c && s) { mgl_datac_mul_num(c, mgl_atoc(s,true)); e->refresh(); }
53 }
54 //-----------------------------------------------------------------------------
divto_cb(Fl_Widget *,void * v)55 void divto_cb(Fl_Widget*, void*v)
56 {
57 TableWindow* e = (TableWindow*)v;
58 const char *s = fl_input(_("Enter number for division of data values"),0);
59 HMDT d = dynamic_cast<HMDT>(e->var);
60 if(d && s) { mgl_data_div_num(d, atof(s)); e->refresh(); }
61 HADT c = dynamic_cast<HADT>(e->var);
62 if(c && s) { mgl_datac_div_num(c, mgl_atoc(s,true)); e->refresh(); }
63 }
64 //-----------------------------------------------------------------------------
65 class XYZDlg : public GeneralDlg
66 {
67 Fl_Box *box;
68 Fl_Check_Button *wch;
69 Fl_Spinner *wmx, *wmy, *wmz;
70 public:
71 bool OK;
rx()72 double rx() { return wmx->value(); }
ry()73 double ry() { return wmy->value(); }
rz()74 double rz() { return wmz->value(); }
nx()75 double nx() { return mgl_int(wmx->value()); }
ny()76 double ny() { return mgl_int(wmy->value()); }
nz()77 double nz() { return mgl_int(wmz->value()); }
ch()78 double ch() { return wch->value(); }
setup(const char * desc,const char * ch=NULL)79 void setup(const char *desc, const char *ch=NULL)
80 {
81 if(desc) box->label(desc);
82 if(ch && *ch)
83 { wch->label(ch); wch->activate(); }
84 else
85 { wch->label(_("not used"));
86 wch->deactivate(); }
87 }
init()88 void init() { OK=false; }
XYZDlg()89 XYZDlg() : GeneralDlg()
90 {
91 w = new Fl_Double_Window(325, 125, _("Change data sizes"));
92 box = new Fl_Box(10, 10, 305, 40);
93 box->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
94 wmx = new Fl_Spinner(30, 55, 75, 25, "mx");
95 wmx->tooltip(_("New size of data on 1st dimension (x-direction)"));
96 wmy = new Fl_Spinner(135, 55, 75, 25, "my");
97 wmy->tooltip(_("New size of data on 2nd dimension (y-direction)"));
98 wmz = new Fl_Spinner(240, 55, 75, 25, "mz");
99 wmz->tooltip(_("New size of data on 3d dimension (z-direction)"));
100 wch = new Fl_Check_Button(15, 90, 95, 25);
101 Fl_Button *o = new Fl_Button(125, 90, 85, 25, _("Cancel"));
102 o->tooltip(_("Do nothing and close this window")); o->callback(cb_dlg_cancel,this);
103 o = new Fl_Return_Button(230, 90, 85, 25, _("Change"));
104 o->tooltip(_("Change (resize) data")); o->callback(cb_dlg_ok,this);
105 w->end(); w->set_modal(); OK=false;
106 }
cb_ok()107 void cb_ok() { OK=true; hide(); }
run()108 bool run() { OK=false; w->show(); while(w->shown()) Fl::wait(); return OK; }
109 } xyz_dlg;
110 //-----------------------------------------------------------------------------
new_dat_cb(Fl_Widget *,void * v)111 void new_dat_cb(Fl_Widget*, void*v)
112 {
113 TableWindow* e = (TableWindow*)v;
114 xyz_dlg.setup(_("Specify new data size\nData will be zero filled"));
115 if(xyz_dlg.run())
116 {
117 HMDT d = dynamic_cast<HMDT>(e->var);
118 if(d)
119 { d->Create(xyz_dlg.nx(), xyz_dlg.ny(), xyz_dlg.nz()); e->refresh(); }
120 HADT c = dynamic_cast<HADT>(e->var);
121 if(c)
122 { c->Create(xyz_dlg.nx(), xyz_dlg.ny(), xyz_dlg.nz()); e->refresh(); }
123 }
124 }
125 //-----------------------------------------------------------------------------
resize_cb(Fl_Widget *,void * v)126 void resize_cb(Fl_Widget*, void*v)
127 {
128 TableWindow* e = (TableWindow*)v;
129 xyz_dlg.setup(_("Specify new data size\nData will be interpolated"));
130 if(xyz_dlg.run())
131 {
132 HMDT d = dynamic_cast<HMDT>(e->var);
133 if(d)
134 { *d = d->Resize(xyz_dlg.nx(), xyz_dlg.ny(), xyz_dlg.nz()); e->refresh(); }
135 HADT c = dynamic_cast<HADT>(e->var);
136 if(c)
137 { *c = c->Resize(xyz_dlg.nx(), xyz_dlg.ny(), xyz_dlg.nz()); e->refresh(); }
138 }
139 }
140 //-----------------------------------------------------------------------------
squeeze_cb(Fl_Widget *,void * v)141 void squeeze_cb(Fl_Widget*, void*v)
142 {
143 TableWindow* e = (TableWindow*)v;
144 xyz_dlg.setup(_("Specify the skipping step\nEach m-th point will be saved only"), _("smoothed")); if(xyz_dlg.run())
145 {
146 HMDT d = dynamic_cast<HMDT>(e->var);
147 if(d)
148 { d->Squeeze(xyz_dlg.nx(), xyz_dlg.ny(), xyz_dlg.nz(), xyz_dlg.ch()); e->refresh(); }
149 HADT c = dynamic_cast<HADT>(e->var);
150 if(c)
151 { c->Squeeze(xyz_dlg.nx(), xyz_dlg.ny(), xyz_dlg.nz(), xyz_dlg.ch()); e->refresh(); }
152 }
153 }
154 //-----------------------------------------------------------------------------
155 class ChngDlg : public GeneralDlg
156 {
157 Fl_Check_Button *dx, *dy, *dz;
158 Fl_Choice *kind, *type;
159 Fl_Float_Input *val;
160 public:
ChngDlg()161 ChngDlg() : GeneralDlg()
162 {
163 Fl_Menu_Item k[]={{_("Smooth")}, {_("CumSum")}, { _("Integrate")},
164 { _("Difference")}, { _("Double diff.")}, { _("Swap parts")},
165 { _("Sinus FFT")}, { _("Cosine FFT")}, { _("Hankel")},
166 { _("Mirror")}, { _("Roll")}, { _("Sew phase")}, { _("Envelop")}, {0}};
167 Fl_Menu_Item t[]={{_("Linear *3")}, {_("Linear *5")}, {_("Parabolic *5")},{0}};
168 w = new Fl_Double_Window(165, 215, _("Change data"));
169 kind = new Fl_Choice(10, 25, 145, 25, _("Type of operation"));
170 kind->align(FL_ALIGN_TOP_LEFT); kind->copy(k);
171 dx = new Fl_Check_Button(10, 55, 140, 25, _("along x"));
172 dy = new Fl_Check_Button(10, 80, 140, 25, _("along y"));
173 dz = new Fl_Check_Button(10, 105, 140, 25, _("along z"));
174 type = new Fl_Choice(10, 145, 145, 25, _("Type of smoothing"));
175 type->align(FL_ALIGN_TOP_LEFT); type->copy(t);
176 val = new Fl_Float_Input(10, 145, 145, 25, _("Numeric parameter"));
177 val->align(FL_ALIGN_TOP_LEFT);
178 Fl_Button *o;
179 o = new Fl_Button(10, 180, 65, 25, _("Cancel")); o->callback(cb_dlg_cancel,this);
180 o = new Fl_Return_Button(90, 180, 65, 25, _("Do")); o->callback(cb_dlg_ok,this);
181 w->end(); w->set_modal();
182 }
cb_ok()183 void cb_ok()
184 {
185 result.clear();
186 if(dx->value()) result += 'x';
187 if(dy->value()) result += 'y';
188 if(dz->value()) result += 'z';
189 if(result.empty())
190 { fl_alert(_("You need to specify direction(s)")); return; }
191 if(type->value()==0) result += '3';
192 if(type->value()==1) result += '5';
193 HMDT d = dynamic_cast<HMDT>(dat);
194 HADT c = dynamic_cast<HADT>(dat);
195 const char *r = result.c_str();
196 bool err = false;
197 double v = val->value() ? atof(val->value()) : 0;
198 if(d) switch(kind->value())
199 {
200 case 0: d->Smooth(r); break;
201 case 1: d->CumSum(r); break;
202 case 2: d->Integral(r); break;
203 case 3: d->Diff(r); break;
204 case 4: d->Diff2(r); break;
205 case 5: d->Swap(r); break;
206 case 6: d->SinFFT(r); break;
207 case 7: d->CosFFT(r); break;
208 case 8: d->Hankel(r); break;
209 case 9: d->Mirror(r); break;
210 case 10:d->Roll(*r ,v); break;
211 case 11:d->Sew(r); break;
212 case 12:d->Envelop(*r); break;
213 }
214 else if(c) switch(kind->value())
215 {
216 case 0: c->Smooth(r); break;
217 case 1: c->CumSum(r); break;
218 case 2: c->Integral(r); break;
219 case 3: c->Diff(r); break;
220 case 4: c->Diff2(r); break;
221 case 5: c->Swap(r); break;
222 case 6: c->SinFFT(r); break;
223 case 7: c->CosFFT(r); break;
224 case 8: c->Hankel(r); break;
225 case 9: c->Mirror(r); break;
226 case 10:c->Roll(*r, v); break;
227 case 11:err=true; break;
228 case 12:c->Envelop(*r); break;
229 }
230 else err=true;
231 if(err) fl_alert(_("Operation is not supported for this type of data."));
232 else hide();
233 }
run(int k,mglDataA * d)234 void run(int k, mglDataA *d)
235 {
236 init(); dat=d; kind->value(k);
237 if(k) { type->hide(); val->show(); }
238 else { type->show(); val->hide(); }
239 w->show(); while(w->shown()) Fl::wait();
240 }
241 } chng_dlg;
242 //-----------------------------------------------------------------------------
smooth_cb(Fl_Widget *,void * v)243 void smooth_cb(Fl_Widget*, void*v)
244 {
245 TableWindow* e = (TableWindow*)v;
246 chng_dlg.run(0, e->var);
247 if(!chng_dlg.result.empty()) e->refresh();
248 }
249 //-----------------------------------------------------------------------------
cumsum_cb(Fl_Widget *,void * v)250 void cumsum_cb(Fl_Widget*, void*v)
251 {
252 TableWindow* e = (TableWindow*)v;
253 chng_dlg.run(1, e->var);
254 if(!chng_dlg.result.empty()) e->refresh();
255 }
256 //-----------------------------------------------------------------------------
integr_cb(Fl_Widget *,void * v)257 void integr_cb(Fl_Widget*, void*v)
258 {
259 TableWindow* e = (TableWindow*)v;
260 chng_dlg.run(2, e->var);
261 if(!chng_dlg.result.empty()) e->refresh();
262 }
263 //-----------------------------------------------------------------------------
diff_cb(Fl_Widget *,void * v)264 void diff_cb(Fl_Widget*, void*v)
265 {
266 TableWindow* e = (TableWindow*)v;
267 chng_dlg.run(3, e->var);
268 if(!chng_dlg.result.empty()) e->refresh();
269 }
270 //-----------------------------------------------------------------------------
diff2_cb(Fl_Widget *,void * v)271 void diff2_cb(Fl_Widget*, void*v)
272 {
273 TableWindow* e = (TableWindow*)v;
274 chng_dlg.run(4, e->var);
275 if(!chng_dlg.result.empty()) e->refresh();
276 }
277 //-----------------------------------------------------------------------------
swap_cb(Fl_Widget *,void * v)278 void swap_cb(Fl_Widget*, void*v)
279 {
280 TableWindow* e = (TableWindow*)v;
281 chng_dlg.run(5, e->var);
282 if(!chng_dlg.result.empty()) e->refresh();
283 }
284 //-----------------------------------------------------------------------------
sinfft_cb(Fl_Widget *,void * v)285 void sinfft_cb(Fl_Widget*, void*v)
286 {
287 TableWindow* e = (TableWindow*)v;
288 chng_dlg.run(6, e->var);
289 if(!chng_dlg.result.empty()) e->refresh();
290 }
291 //-----------------------------------------------------------------------------
cosfft_cb(Fl_Widget *,void * v)292 void cosfft_cb(Fl_Widget*, void*v)
293 {
294 TableWindow* e = (TableWindow*)v;
295 chng_dlg.run(7, e->var);
296 if(!chng_dlg.result.empty()) e->refresh();
297 }
298 //-----------------------------------------------------------------------------
hankel_cb(Fl_Widget *,void * v)299 void hankel_cb(Fl_Widget*, void*v)
300 {
301 TableWindow* e = (TableWindow*)v;
302 chng_dlg.run(8, e->var);
303 if(!chng_dlg.result.empty()) e->refresh();
304 }
305 //-----------------------------------------------------------------------------
mirror_cb(Fl_Widget *,void * v)306 void mirror_cb(Fl_Widget*, void*v)
307 {
308 TableWindow* e = (TableWindow*)v;
309 chng_dlg.run(9, e->var);
310 if(!chng_dlg.result.empty()) e->refresh();
311 }
312 //-----------------------------------------------------------------------------
roll_cb(Fl_Widget *,void * v)313 void roll_cb(Fl_Widget*, void*v)
314 {
315 TableWindow* e = (TableWindow*)v;
316 chng_dlg.run(10, e->var);
317 if(!chng_dlg.result.empty()) e->refresh();
318 }
319 //-----------------------------------------------------------------------------
sew_cb(Fl_Widget *,void * v)320 void sew_cb(Fl_Widget*, void*v)
321 {
322 TableWindow* e = (TableWindow*)v;
323 chng_dlg.run(11, e->var);
324 if(!chng_dlg.result.empty()) e->refresh();
325 }
326 //-----------------------------------------------------------------------------
envelop_cb(Fl_Widget *,void * v)327 void envelop_cb(Fl_Widget*, void*v)
328 {
329 TableWindow* e = (TableWindow*)v;
330 chng_dlg.run(12, e->var);
331 if(!chng_dlg.result.empty()) e->refresh();
332 }
333 //-----------------------------------------------------------------------------
334 class NwdtDlg : public GeneralDlg
335 {
336 Fl_Check_Button *dx, *dy, *dz;
337 Fl_Choice *kind;
338 Fl_Input *name;
339 public:
NwdtDlg()340 NwdtDlg() : GeneralDlg()
341 {
342 Fl_Menu_Item k[]={{_("Summation of")}, {_("Maximum of")}, { _("Minimum of")}, { _("Pulse prop.")}, {0}};
343 w = new Fl_Double_Window(165, 215, _("Extract data"));
344 kind = new Fl_Choice(10, 25, 145, 25, _("Type of operation"));
345 kind->align(FL_ALIGN_TOP_LEFT); kind->copy(k);
346 dx = new Fl_Check_Button(10, 55, 140, 25, _("along x"));
347 dy = new Fl_Check_Button(10, 80, 140, 25, _("along y"));
348 dz = new Fl_Check_Button(10, 105, 140, 25, _("along z"));
349 name = new Fl_Input(10, 145, 145, 25, _("Name for output"));
350 name->align(FL_ALIGN_TOP_LEFT);
351
352 Fl_Button *o;
353 o = new Fl_Button(10, 180, 65, 25, _("Cancel")); o->callback(cb_dlg_cancel,this);
354 o = new Fl_Return_Button(90, 180, 65, 25, _("Do")); o->callback(cb_dlg_ok,this);
355 w->set_modal(); w->end();
356 }
cb_ok()357 void cb_ok()
358 {
359 result.clear();
360 if(dx->value()) result += 'x';
361 if(dy->value()) result += 'y';
362 if(dz->value()) result += 'z';
363 if(result.empty())
364 { fl_alert(_("You need to specify direction(s)")); return; }
365 const char *s = name->value();
366 if(!s || !s[0])
367 { fl_alert(_("You need to provide output name")); return; }
368 mglDataA *out = Parse->AddVar(s);
369
370 HMDT d = dynamic_cast<HMDT>(dat);
371 HADT c = dynamic_cast<HADT>(dat);
372 const char *r = result.c_str();
373 if(d) switch(kind->value())
374 {
375 case 0: *out = d->Sum(r); break;
376 case 1: *out = d->Max(r); break;
377 case 2: *out = d->Min(r); break;
378 case 3: *out = d->Pulse(*r);break;
379 }
380 if(c) switch(kind->value())
381 {
382 case 0: *out = c->Sum(r); break;
383 case 1: *out = c->Max(r); break;
384 case 2: *out = c->Min(r); break;
385 case 3: *out = mglData(true,mgl_data_pulse(c,*r)); break;
386 }
387 hide();
388 }
run(int k,mglDataA * d)389 void run(int k, mglDataA *d)
390 {
391 init(); dat=d; kind->value(k);
392 w->show(); while(w->shown()) Fl::wait();
393 }
394 } nwdt_dlg;
395 //-----------------------------------------------------------------------------
asum_cb(Fl_Widget *,void * v)396 void asum_cb(Fl_Widget*, void*v)
397 {
398 TableWindow* e = (TableWindow*)v;
399 nwdt_dlg.run(0, e->var);
400 if(!chng_dlg.result.empty()) e->refresh();
401 }
402 //-----------------------------------------------------------------------------
amax_cb(Fl_Widget *,void * v)403 void amax_cb(Fl_Widget*, void*v)
404 {
405 TableWindow* e = (TableWindow*)v;
406 nwdt_dlg.run(1, e->var);
407 if(!chng_dlg.result.empty()) e->refresh();
408 }
409 //-----------------------------------------------------------------------------
amin_cb(Fl_Widget *,void * v)410 void amin_cb(Fl_Widget*, void*v)
411 {
412 TableWindow* e = (TableWindow*)v;
413 nwdt_dlg.run(2, e->var);
414 if(!chng_dlg.result.empty()) e->refresh();
415 }
416 //-----------------------------------------------------------------------------
pulse_cb(Fl_Widget *,void * v)417 void pulse_cb(Fl_Widget*, void*v)
418 {
419 TableWindow* e = (TableWindow*)v;
420 nwdt_dlg.run(3, e->var);
421 if(!chng_dlg.result.empty()) e->refresh();
422 }
423 //-----------------------------------------------------------------------------
load_dat_cb(Fl_Widget *,void * v)424 void load_dat_cb(Fl_Widget*, void*v)
425 {
426 TableWindow* e = (TableWindow*)v;
427 const char *newfile = mgl_file_chooser(_("Load Data?"),
428 _("DAT Files \t*.{dat,csv}\nHDF Files \t*.{h5,hdf}"));
429 if(newfile)
430 {
431 const char *ext = fl_filename_ext(newfile);
432 HMDT d = dynamic_cast<HMDT>(e->var);
433 HADT c = dynamic_cast<HADT>(e->var);
434 if(!strcmp(ext,"h5") || !strcmp(ext,"hdf")) // this is HDF file
435 { // TODO add dialog with choice of HDF names
436 const char *name = fl_input(_("Enter name of data"),"");
437 if(name)
438 {
439 if(d) d->ReadHDF(newfile,name);
440 if(c) c->ReadHDF(newfile,name);
441 e->refresh();
442 }
443 }
444 else
445 {
446 if(d) d->Read(newfile);
447 if(c) c->Read(newfile);
448 e->refresh();
449 }
450 }
451 }
452 //-----------------------------------------------------------------------------
save_dat_cb(Fl_Widget *,void * v)453 void save_dat_cb(Fl_Widget*, void*v)
454 {
455 TableWindow* e = (TableWindow*)v;
456 const char *newfile = mgl_file_chooser(_("Save Data?"),
457 _("DAT Files \t*.{dat,csv}\nHDF Files \t*.{h5,hdf}"), true);
458 if(newfile)
459 {
460 const char *ext = fl_filename_ext(newfile);
461 if(!strcmp(ext,"h5") || !strcmp(ext,"hdf")) // this is HDF file
462 {
463 std::string name = wcstombs(e->var->Name());
464 e->var->SaveHDF(newfile, name.c_str());
465 }
466 else e->var->Save(newfile);
467 }
468 }
469 //-----------------------------------------------------------------------------
exp_dat_cb(Fl_Widget *,void * v)470 void exp_dat_cb(Fl_Widget*, void*v)
471 {
472 TableWindow* e = (TableWindow*)v;
473 const char *newfile = mgl_file_chooser(_("Export Data?"),
474 _("PNG Files \t*.png"), true);
475 if(newfile)
476 { // TODO show dialog for color scheme
477 const char *scheme = fl_input(_("Enter color scheme"),MGL_DEF_SCH);
478 if(scheme) e->var->Export(newfile,scheme);
479 }
480 }
481 //-----------------------------------------------------------------------------
imp_dat_cb(Fl_Widget *,void * v)482 void imp_dat_cb(Fl_Widget*, void*v)
483 {
484 TableWindow* e = (TableWindow*)v;
485 const char *newfile = mgl_file_chooser(_("Import Data?"),
486 _("PNG Files \t*.png"));
487 HMDT d = dynamic_cast<HMDT>(e->var);
488 if(d && newfile)
489 {
490 const char *scheme = fl_input(_("Enter color scheme"),MGL_DEF_SCH);
491 if(scheme)
492 { d->Import(newfile,scheme); e->refresh(); }
493 }
494 if(!d) fl_alert(_("This operation is not supported for this kind of data."));
495 }
496 //-----------------------------------------------------------------------------
list_dat_cb(Fl_Widget *,void * v)497 void list_dat_cb(Fl_Widget*, void*v)
498 {
499 TableWindow* e = (TableWindow*)v;
500 HMDT d = dynamic_cast<HMDT>(e->var);
501 HADT c = dynamic_cast<HADT>(e->var);
502 if(!d && !c)
503 { fl_message(_("Incorrect type of base data")); return; }
504 if(e->var->GetNz()>1) fl_message(_("Only current slice will be inserted"));
505
506 std::string list = "list " + wcstombs(e->var->Name());
507 long k=e->get_slice(), nx=e->var->GetNx(), ny=e->var->GetNy();
508 for(long j=0;j<ny;j++)
509 {
510 for(long i=0;i<nx;i++)
511 {
512 if(d) list += '\t'+mgl_str_num(d->a[i+nx*(j+k*ny)]);
513 if(c) list += '\t'+mgl_str_num(c->a[i+nx*(j+k*ny)]);
514 }
515 if(j<ny-1) list += "\t|";
516 }
517 textbuf->insert(0,list.c_str());
518 }
519 //-----------------------------------------------------------------------------
modify_cb(Fl_Widget *,void * v)520 void modify_cb(Fl_Widget*, void*v)
521 {
522 TableWindow* e = (TableWindow*)v;
523 const char *eq=fl_input(_("Enter formula for data modification\nHere x, y, z in range [0,1], u is data value"),0);
524 if(eq)
525 {
526 HMDT d = dynamic_cast<HMDT>(e->var);
527 HADT c = dynamic_cast<HADT>(e->var);
528 if(d) { d->Modify(eq); e->refresh(); }
529 if(c) { c->Modify(eq); e->refresh(); }
530 }
531 }
532 //-----------------------------------------------------------------------------
533 class NrmDlg : public GeneralDlg
534 {
535 Fl_Value_Input *wmin, *wmax;
536 Fl_Choice *dir;
537 Fl_Check_Button *wsym;
538 public:
NrmDlg()539 NrmDlg() : GeneralDlg()
540 {
541 Fl_Menu_Item k[]={{"x"}, {"y"}, { "z"}, {0}};
542 w = new Fl_Double_Window(135, 215);
543 wmin = new Fl_Value_Input(10, 25, 115, 25, _("Minimal value (v1)"));
544 wmin->align(FL_ALIGN_TOP_LEFT);
545 wmin->tooltip(_("Minimal value for resulting data values"));
546 wmax = new Fl_Value_Input(10, 70, 115, 25, _("Maximal value (v2)"));
547 wmax->align(FL_ALIGN_TOP_LEFT);
548 wmax->tooltip(_("Maximal value for resulting data values"));
549 dir = new Fl_Choice(10, 115, 115, 25, _("Direction"));
550 dir->align(FL_ALIGN_TOP_LEFT); dir->copy(k); dir->value(0);
551 dir->tooltip(_("Direction along which data will be filled"));
552 wsym = new Fl_Check_Button(10, 115, 115, 25, _("Symmetrical range"));
553 wsym->tooltip(_("Normalize in symmetrical range: -max(|v1|,|v2|) ... max(|v1|,|v2|)"));
554
555 Fl_Button *o;
556 o = new Fl_Button(25, 150, 85, 25, _("Cancel")); o->callback(cb_dlg_cancel,this);
557 o->tooltip(_("Do nothing and close this window"));
558 o = new Fl_Return_Button(25, 180, 85, 25, _("Change")); o->callback(cb_dlg_ok,this);
559 o->tooltip(_("Change data values and close this window"));
560 w->set_modal(); w->end();
561 }
vmin()562 double vmin() { return wmin->value(); }
vmax()563 double vmax() { return wmax->value(); }
sym()564 int sym() { return wsym->value(); }
ok()565 bool ok() { return !result.empty(); }
cb_ok()566 void cb_ok()
567 { result = dir->value(); hide(); }
run(const char * lbl)568 void run(const char *lbl)
569 {
570 init(); w->label(lbl?lbl:"");
571 w->show(); while(w->shown()) Fl::wait();
572 }
573 } nrm_dlg;
574 //-----------------------------------------------------------------------------
fill_cb(Fl_Widget *,void * v)575 void fill_cb(Fl_Widget*, void*v)
576 {
577 TableWindow* e = (TableWindow*)v;
578 nrm_dlg.run(_("Fill in range"));
579 if(nrm_dlg.ok())
580 {
581 HMDT d = dynamic_cast<HMDT>(e->var);
582 HADT c = dynamic_cast<HADT>(e->var);
583 char ch = nrm_dlg.result[0];
584 if(d) { d->Fill(nrm_dlg.vmin(),nrm_dlg.vmax(),ch); e->refresh(); }
585 if(c) { c->Fill(nrm_dlg.vmin(),nrm_dlg.vmax(),ch); e->refresh(); }
586 }
587 }
588 //-----------------------------------------------------------------------------
normal_cb(Fl_Widget *,void * v)589 void normal_cb(Fl_Widget*, void*v)
590 {
591 TableWindow* e = (TableWindow*)v;
592 nrm_dlg.run(_("Fill in range"));
593 if(nrm_dlg.ok())
594 {
595 HMDT d = dynamic_cast<HMDT>(e->var);
596 HADT c = dynamic_cast<HADT>(e->var);
597 if(d) { d->Norm(nrm_dlg.vmin(),nrm_dlg.vmax(),nrm_dlg.sym()); e->refresh(); }
598 if(c) { c->Fill(nrm_dlg.vmin(),nrm_dlg.vmax(),nrm_dlg.sym()); e->refresh(); }
599 }
600 }
601 //-----------------------------------------------------------------------------
602 struct CropDlg : public GeneralDlg
603 {
604 Fl_Spinner *x1,*x2, *y1,*y2, *z1,*z2;
CropDlgCropDlg605 CropDlg() : GeneralDlg()
606 {
607 w = new Fl_Double_Window(230, 155, _("Crop data"));
608 x1 = new Fl_Spinner(45, 25, 80, 25, _("From")); x1->align(FL_ALIGN_TOP);
609 x2 = new Fl_Spinner(140, 25, 80, 25, _("To")); x2->align(FL_ALIGN_TOP);
610 y1 = new Fl_Spinner(45, 55, 80, 25);
611 y2 = new Fl_Spinner(140, 55, 80, 25);
612 z1 = new Fl_Spinner(45, 85, 80, 25);
613 z2 = new Fl_Spinner(140, 85, 80, 25);
614
615 new Fl_Box(15, 25, 25, 25, "X");
616 new Fl_Box(15, 55, 25, 25, "Y");
617 new Fl_Box(15, 85, 25, 25, "Z");
618 Fl_Button *o;
619 o = new Fl_Button(45, 120, 75, 25, _("Cancel")); o->callback(cb_dlg_cancel,this);
620 o->tooltip(_("Do nothing and close this window"));
621 o = new Fl_Return_Button(145, 120, 75, 25, _("OK")); o->callback(cb_dlg_ok,this);
622 o->tooltip(_("Change data values and close this window"));
623 w->set_modal(); w->end();
624 }
initCropDlg625 void init()
626 {
627 long nx=dat->GetNx(), ny=dat->GetNy(), nz=dat->GetNz();
628 x1->range(0,nx-1); x1->value(0);
629 x2->range(0,nx-1); x2->value(nx-1);
630 y1->range(0,nx-1); y1->value(0);
631 y2->range(0,nx-1); y2->value(ny-1);
632 z1->range(0,nx-1); z1->value(0);
633 z2->range(0,nx-1); z2->value(nz-1);
634 }
cb_okCropDlg635 void cb_ok()
636 {
637 long n1,n2;
638 HMDT d = dynamic_cast<HMDT>(dat);
639 HADT c = dynamic_cast<HADT>(dat);
640 n1=mgl_int(x1->value()); n2=mgl_int(x2->value());
641 if(d) d->Crop(n1,n2,'x');
642 if(c) c->Crop(n1,n2,'x');
643 n1=mgl_int(y1->value()); n2=mgl_int(y2->value());
644 if(d) d->Crop(n1,n2,'y');
645 if(c) c->Crop(n1,n2,'y');
646 n1=mgl_int(z1->value()); n2=mgl_int(z2->value());
647 if(d) d->Crop(n1,n2,'z');
648 if(c) c->Crop(n1,n2,'z');
649 hide();
650 }
runCropDlg651 void run(mglDataA *d)
652 {
653 dat = d; init();
654 w->show(); while(w->shown()) Fl::wait();
655 }
656 } crop_dlg;
657 //-----------------------------------------------------------------------------
crop_cb(Fl_Widget *,void * v)658 void crop_cb(Fl_Widget*, void*v)
659 {
660 TableWindow* e = (TableWindow*)v;
661 crop_dlg.run(e->var); e->refresh();
662 }
663 //-----------------------------------------------------------------------------
664 struct TrspDlg : public GeneralDlg
665 {
666 Fl_Choice *how;
667 public:
TrspDlgTrspDlg668 TrspDlg() : GeneralDlg()
669 {
670 Fl_Menu_Item k[]={{"yxz"}, {"zxy"}, {"zyx"}, {"yzx"}, {"xzy"}, {0}};
671 w = new Fl_Double_Window(200, 90, _("Transpose data"));
672 how = new Fl_Choice(10, 20, 180, 25, _("New order of dimensions"));
673 how->align(FL_ALIGN_TOP_LEFT); how->copy(k); how->value(0);
674 Fl_Button *o;
675 o = new Fl_Button(30, 55, 75, 25, _("Cancel")); o->callback(cb_dlg_cancel,this);
676 o->tooltip(_("Do nothing and close this window"));
677 o = new Fl_Return_Button(115, 55, 75, 25, _("Do")); o->callback(cb_dlg_ok,this);
678 o->tooltip(_("Change data values and close this window"));
679 w->set_modal(); w->end();
680 }
cb_okTrspDlg681 void cb_ok()
682 {
683 HMDT d = dynamic_cast<HMDT>(dat);
684 HADT c = dynamic_cast<HADT>(dat);
685 if(d) d->Transpose(how->text());
686 if(c) c->Transpose(how->text());
687 hide();
688 }
runTrspDlg689 void run(mglDataA *d)
690 {
691 dat = d; init();
692 w->show(); while(w->shown()) Fl::wait();
693 }
694 } trsp_dlg;
695 //-----------------------------------------------------------------------------
transp_cb(Fl_Widget *,void * v)696 void transp_cb(Fl_Widget*, void*v)
697 {
698 TableWindow* e = (TableWindow*)v;
699 trsp_dlg.run(e->var); e->refresh();
700 }
701 //-----------------------------------------------------------------------------
first_sl_cb(Fl_Widget *,void * v)702 void first_sl_cb(Fl_Widget*, void*v)
703 {
704 TableWindow* e = (TableWindow*)v;
705 e->slice->value(0);
706 e->set_slice(0);
707 e->go_home();
708 }
709 //-----------------------------------------------------------------------------
last_sl_cb(Fl_Widget *,void * v)710 void last_sl_cb(Fl_Widget*, void*v)
711 {
712 TableWindow* e = (TableWindow*)v;
713 e->slice->value(e->num_slice()-1);
714 e->set_slice(e->num_slice()-1);
715 e->go_home();
716 }
717 //-----------------------------------------------------------------------------
prev_sl_cb(Fl_Widget *,void * v)718 void prev_sl_cb(Fl_Widget*, void*v)
719 {
720 TableWindow* e = (TableWindow*)v;
721 int p = int(e->slice->value())-1;
722 if(p<0) p = 0;
723 e->slice->value(p); e->set_slice(p);
724 e->go_home();
725 }
726 //-----------------------------------------------------------------------------
next_sl_cb(Fl_Widget *,void * v)727 void next_sl_cb(Fl_Widget*, void*v)
728 {
729 TableWindow* e = (TableWindow*)v;
730 int p = int(e->slice->value())+1;
731 if(p>=e->num_slice()) p = e->num_slice()-1;
732 e->slice->value(p); e->set_slice(p);
733 e->go_home();
734 }
735 //-----------------------------------------------------------------------------
first_cl_cb(Fl_Widget *,void * v)736 void first_cl_cb(Fl_Widget*, void*v)
737 {
738 TableWindow* e = (TableWindow*)v;
739 e->go_home();
740 }
741 //-----------------------------------------------------------------------------
change_sl_cb(Fl_Widget * w,void * v)742 void change_sl_cb(Fl_Widget*w, void*v)
743 {
744 TableWindow* e = (TableWindow*)v;
745 e->set_slice(long(e->slice->value()));
746 e->go_home();
747 }
748 //-----------------------------------------------------------------------------
749 Fl_Menu_Item tablemenu[60] = {
750 { _("File"), 0, 0, 0, FL_SUBMENU },
751 { _("Load from file"),0, load_dat_cb },
752 { _("Import from PNG"),0, imp_dat_cb },
753 { _("Save to file"), 0, save_dat_cb },
754 { _("Export to PNG"), 0, exp_dat_cb, 0, FL_MENU_DIVIDER },
755 { _("Insert as 'list'"),0, list_dat_cb },
756 // { _("Plot data"), 0, plot_dat_cb },
757 // { _("Info for data"), 0, info_dat_cb },
758 { 0 },
759 { _("Sizes"), 0, 0, 0, FL_SUBMENU },
760 { _("Create new"), 0, new_dat_cb },
761 { _("Resize"), 0, resize_cb },
762 { _("Squeeze"), 0, squeeze_cb },
763 { _("Crop"), 0, crop_cb },
764 { _("Transpose"), 0, transp_cb },
765 // { _("Extend"), 0, extend_cb },
766 { 0 },
767 { _("Fill"), 0, 0, 0, FL_SUBMENU },
768 { _("By formula"), 0, modify_cb },
769 { _("In range"), 0, fill_cb },
770 { _("Normalize"), 0, normal_cb },
771 { 0 },
772 { _("Change"), 0, 0, 0, FL_SUBMENU },
773 { _("Smooth"), 0, smooth_cb },
774 { _("CumSum"), 0, cumsum_cb },
775 { _("Integrate"), 0, integr_cb },
776 { _("Difference"),0, diff_cb },
777 { _("Laplacian"), 0, diff2_cb },
778 { _("Swap parts"),0, swap_cb },
779 { _("Sin FFT"), 0, sinfft_cb },
780 { _("Cos FFT"), 0, cosfft_cb },
781 { _("Hankel"), 0, hankel_cb },
782 // { _("Wavelet"), 0, wavelet_cb },
783 { _("Mirror"), 0, mirror_cb },
784 { _("Roll"), 0, roll_cb },
785 { _("Sew phase"), 0, sew_cb },
786 { _("Envelop"), 0, envelop_cb },
787 { 0 },
788 { _("Another"), 0, 0, 0, FL_SUBMENU },
789 // { _("Histogram of"), 0, hist_cb },
790 { _("Summation of"), 0, asum_cb },
791 { _("Maximum of"), 0, amax_cb },
792 { _("Minimum of"), 0, amin_cb },
793 { _("Pulse prop."), 0, pulse_cb },
794 { 0 },
795 { _("Operations"), 0, 0, 0, FL_SUBMENU },
796 { _("Add to"), 0, addto_cb },
797 { _("Subtract to"),0, subto_cb },
798 { _("Multiply by"),0, multo_cb },
799 { _("Divide by"), 0, divto_cb },
800 { 0 },
801 { _("Navigation"), 0, 0, 0, FL_SUBMENU },
802 { _("First slice"), FL_CTRL + FL_F + 1, first_sl_cb },
803 { _("Prev slice"), FL_CTRL + FL_F + 2, prev_sl_cb },
804 { _("Next slice"), FL_CTRL + FL_F + 3, next_sl_cb },
805 { _("Last slice"), FL_CTRL + FL_F + 4, last_sl_cb, 0, FL_MENU_DIVIDER },
806 { _("First cell"), FL_ALT + FL_F + 1, first_cl_cb },
807 // { _("Last cell"), FL_ALT + FL_F + 2, last_cl_cb },
808 // { _("Center grid"), FL_ALT + FL_F + 3, center_cl_cb },
809 { 0 },
810 { 0 }
811 };
812 //-----------------------------------------------------------------------------
plot_dat_cb(Fl_Widget *,void * v)813 void plot_dat_cb(Fl_Widget*,void *v)
814 {
815 TableWindow *e=(TableWindow*)v;
816 info_dlg_cb(e->var);
817 }
818 //-----------------------------------------------------------------------------
819 #include "../widgets/image.h"
820 #include "xpm/document-import.xpm"
821 #include "xpm/document-export.xpm"
822 #include "xpm/diff.xpm"
823 #include "xpm/func.xpm"
824 #include "xpm/size.xpm"
825 #include "xpm/tran.xpm"
826 #include "xpm/crop.xpm"
827 #include "xpm/go-first.xpm"
828 #include "xpm/go-last.xpm"
TableWindow(ScriptWindow * e)829 TableWindow::TableWindow(ScriptWindow *e)
830 {
831 main = e;
832 const int ww = 600, hh = 430; // initial width (>300) and height (>430)
833 w = new Fl_Double_Window(ww,430); var = 0;
834 menu = new Fl_Menu_Bar(0, 0, ww, 30); menu->copy(tablemenu, this);
835 Fl_Button *o;
836 Fl_Group *g = new Fl_Group(0,0,30,350);
837 o = new Fl_Button(0, 30, 25, 25); o->image(img_new);
838 o->callback(new_dat_cb,this); o->tooltip(_("Create new data with zero filling"));
839 o = new Fl_Button(0, 55, 25, 25); o->image(img_load);
840 o->callback(load_dat_cb,this); o->tooltip(_("Load data from file"));
841 o = new Fl_Button(0, 80, 25, 25); o->image(new Fl_Pixmap(document_import_xpm));
842 o->callback(imp_dat_cb,this); o->tooltip(_("Import data from PNG file"));
843 o = new Fl_Button(0, 105, 25, 25); o->image(img_save);
844 o->callback(save_dat_cb,this); o->tooltip(_("Save data to file"));
845 o = new Fl_Button(0, 130, 25, 25); o->image(new Fl_Pixmap(document_export_xpm));
846 o->callback(exp_dat_cb,this); o->tooltip(_("Export data to PNG file"));
847
848 o = new Fl_Button(0, 160, 25, 25); o->image(img_insert);
849 o->callback(list_dat_cb,this); o->tooltip(_("Insert to script as 'list' command"));
850 o = new Fl_Button(0, 185, 25, 25); o->image(img_plot);
851 o->callback(plot_dat_cb,this); o->tooltip(_("Data information and preview."));
852
853 o = new Fl_Button(0, 215, 25, 25); o->image(new Fl_Pixmap(diff_xpm));
854 o->callback(smooth_cb,this); o->tooltip(_("Apply operator (smoothing, integration, difference ...) to data"));
855 o = new Fl_Button(0, 240, 25, 25); o->image(new Fl_Pixmap(func_xpm));
856 o->callback(modify_cb,this); o->tooltip(_("Fill data by formula"));
857 o = new Fl_Button(0, 265, 25, 25); o->image(new Fl_Pixmap(size_xpm));
858 o->callback(resize_cb,this); o->tooltip(_("Resize data with smoothing"));
859 o = new Fl_Button(0, 290, 25, 25); o->image(new Fl_Pixmap(crop_xpm));
860 o->callback(crop_cb,this); o->tooltip(_("Crop (cut off edges) data"));
861 o = new Fl_Button(0, 315, 25, 25); o->image(new Fl_Pixmap(tran_xpm));
862 o->callback(transp_cb,this); o->tooltip(_("Transpose data dimensions"));
863 g->end(); g->resizable(0);
864
865 g = new Fl_Group(30, 30, 200, 30);
866 o = new Fl_Button(30, 30, 25, 25); o->image(new Fl_Pixmap(go_first_xpm));
867 o->callback(first_sl_cb,this); o->tooltip(_("Go to first slice for 3D data (Ctrl-F1)."));
868 slice = new Fl_Counter(55, 30, 90, 25, 0); slice->callback(change_sl_cb,this);
869 slice->lstep(10); slice->step(1); slice->tooltip(_("Id of slice on third (z-) dimension"));
870 o = new Fl_Button(147, 30, 25, 25); o->image(new Fl_Pixmap(go_last_xpm));
871 o->callback(last_sl_cb,this); o->tooltip(_("Go to last slice for 3D data (Ctrl-F4)."));
872 g->end(); g->resizable(0);
873
874 data = new Fl_Data_Table(30,60,ww-30,hh-60);
875 data->row_header(1); data->row_header_width(80);
876 data->row_resize(1); data->rows(1);
877 data->row_height_all(25);
878 data->col_header(1); data->col_header_height(25);
879 data->col_resize(1); data->cols(1);
880 data->col_width_all(80);
881 data->tooltip(_("Colors denote values: magenta - local max, cyan - local min,\n"
882 "\tred - Re(v)>0, blue - Re(v)<0, purple - Im(v)>0, teal - Im(v)<0."));
883
884 w->end(); w->resizable(data);
885 }
886 //-----------------------------------------------------------------------------
~TableWindow()887 TableWindow::~TableWindow() { if(var) var->o=NULL; Fl::delete_widget(w); }
888 //-----------------------------------------------------------------------------
delete_cb(void * v)889 void delete_cb(void *v)
890 {
891 if(v)
892 {
893 TableWindow *w = (TableWindow *)v;
894 w->var->o=NULL; delete w;
895 }
896 }
897 //-----------------------------------------------------------------------------
update(mglDataA * v)898 void TableWindow::update(mglDataA *v)
899 {
900 static std::string name;
901 if(v==0) return;
902 name = wcstombs(v->Name());
903 w->label(name.c_str());
904 v->func = delete_cb;
905 if(var) var->o = 0;
906 var = v; v->o = this;
907 refresh();
908 }
909 //-----------------------------------------------------------------------------
refresh()910 void TableWindow::refresh()
911 {
912 if(var==0) return;
913 w->deactivate(); nz = var->GetNz();
914 sl = 0; slice->range(0,nz-1);
915
916 data->rows(var->GetNy()); data->cols(var->GetNx());
917 data->ny = var->GetNy(); data->nx = var->GetNx();
918 data->data = var;
919 w->activate();
920 // show();
921 }
922 //-----------------------------------------------------------------------------
set_slice(long s)923 void TableWindow::set_slice(long s)
924 {
925 if(s>=0 && s<nz)
926 {
927 data->sl = sl = s;
928 refresh();
929 }
930 }
931 //-----------------------------------------------------------------------------
go_home()932 void TableWindow::go_home()
933 {
934 }
935 //-----------------------------------------------------------------------------
936