1 // generated by Fast Light User Interface Designer (fluid) version 1.0100
2
3 #include "ObjectEditor.h"
4 // Quat - A 3D fractal generation program
5 // Copyright (C) 1997-2000 Dirk Meyer
6 // (email: dirk.meyer@studserv.uni-stuttgart.de)
7 // mail: Dirk Meyer
8 // Marbacher Weg 29
9 // D-71334 Waiblingen
10 // Germany
11 //
12 // This program is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License
14 // as published by the Free Software Foundation; either version 2
15 // of the License, or (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 //#include <iostream>
29 //#include <string.h>
30 #include <cmath> // fabs
31 #include "ChildWindow.h"
32 #define VD(a) (a)->value()
33 #define VI(a) static_cast<int>((a)->value())
34 #include "MandelPreview.h"
35
cb_maxiter_i(Fl_Value_Input * o,void *)36 inline void ObjectEditor::cb_maxiter_i(Fl_Value_Input* o, void*) {
37 MP->maxiter(VI(o));
38 frac.maxiter = VI(o);
39 o->color(FL_WHITE);
40 if (VI(o)<=0) o->color(FL_RED);
41 if (VI(o)>65535) o->color(FL_RED);
42 o->redraw();
43 }
cb_maxiter(Fl_Value_Input * o,void * v)44 void ObjectEditor::cb_maxiter(Fl_Value_Input* o, void* v) {
45 ((ObjectEditor*)(o->parent()->user_data()))->cb_maxiter_i(o,v);
46 }
47
cb_lvalue_i(Fl_Value_Input * o,void *)48 inline void ObjectEditor::cb_lvalue_i(Fl_Value_Input* o, void*) {
49 frac.lvalue = VD(o);
50 o->color(FL_WHITE);
51 if (fabs(VD(o))>2.0) o->color(FL_YELLOW);
52 if (fabs(VD(o))>=1000000.0) o->color(FL_RED);
53 o->redraw();
54 }
cb_lvalue(Fl_Value_Input * o,void * v)55 void ObjectEditor::cb_lvalue(Fl_Value_Input* o, void* v) {
56 ((ObjectEditor*)(o->parent()->user_data()))->cb_lvalue_i(o,v);
57 }
58
cb_bailout_i(Fl_Value_Input * o,void *)59 inline void ObjectEditor::cb_bailout_i(Fl_Value_Input* o, void*) {
60 MP->bailout(VD(o));
61 frac.bailout = VD(o);
62 o->color(FL_WHITE);
63 if (VD(o) <= 0.0 || VD(o) >= 1E20) o->color(FL_RED);
64 else if (VD(o) < 4.0) o->color(FL_YELLOW);
65 else o->color(FL_WHITE);
66 o->redraw();
67 }
cb_bailout(Fl_Value_Input * o,void * v)68 void ObjectEditor::cb_bailout(Fl_Value_Input* o, void* v) {
69 ((ObjectEditor*)(o->parent()->user_data()))->cb_bailout_i(o,v);
70 }
71
cb_formula_i(Fl_Choice * o,void *)72 inline void ObjectEditor::cb_formula_i(Fl_Choice* o, void*) {
73 MP->formula(VI(o));
74 frac.formula = VI(o);
75 formula_changed();
76 }
cb_formula(Fl_Choice * o,void * v)77 void ObjectEditor::cb_formula(Fl_Choice* o, void* v) {
78 ((ObjectEditor*)(o->parent()->user_data()))->cb_formula_i(o,v);
79 }
80
81 Fl_Menu_Item ObjectEditor::menu_formula[] = {
82 {"Classical Julia", 0x61, 0, 0, 0, 0, 0, 12, 0},
83 {"Lambda Julia", 0x62, 0, 0, 0, 0, 0, 12, 0},
84 {"x[n+1] = x[n]*ln(x[n]) - c", 0x63, 0, 0, 0, 0, 0, 12, 0},
85 {"Cubic Julia", 0x64, 0, 0, 0, 0, 0, 12, 0},
86 {"x[n+1] = x[n]^p1-c", 0x65, 0, 0, 0, 0, 0, 12, 0},
87 {0}
88 };
89
cb_cre_i(Fl_Value_Input * o,void *)90 inline void ObjectEditor::cb_cre_i(Fl_Value_Input* o, void*) {
91 MP->SetCX(VD(o));
92 frac.c[0] = VD(o);
93 }
cb_cre(Fl_Value_Input * o,void * v)94 void ObjectEditor::cb_cre(Fl_Value_Input* o, void* v) {
95 ((ObjectEditor*)(o->parent()->user_data()))->cb_cre_i(o,v);
96 }
97
cb_ci_i(Fl_Value_Input * o,void *)98 inline void ObjectEditor::cb_ci_i(Fl_Value_Input* o, void*) {
99 MP->SetCY(VD(o));
100 frac.c[1] = VD(o);
101 }
cb_ci(Fl_Value_Input * o,void * v)102 void ObjectEditor::cb_ci(Fl_Value_Input* o, void* v) {
103 ((ObjectEditor*)(o->parent()->user_data()))->cb_ci_i(o,v);
104 }
105
cb_cj_i(Fl_Value_Input * o,void *)106 inline void ObjectEditor::cb_cj_i(Fl_Value_Input* o, void*) {
107 MP->cj(VD(o));
108 frac.c[2] = VD(o);
109 }
cb_cj(Fl_Value_Input * o,void * v)110 void ObjectEditor::cb_cj(Fl_Value_Input* o, void* v) {
111 ((ObjectEditor*)(o->parent()->user_data()))->cb_cj_i(o,v);
112 }
113
cb_ck_i(Fl_Value_Input * o,void *)114 inline void ObjectEditor::cb_ck_i(Fl_Value_Input* o, void*) {
115 MP->ck(VD(o));
116 frac.c[3] = VD(o);
117 }
cb_ck(Fl_Value_Input * o,void * v)118 void ObjectEditor::cb_ck(Fl_Value_Input* o, void* v) {
119 ((ObjectEditor*)(o->parent()->user_data()))->cb_ck_i(o,v);
120 }
121
cb_up_i(Fl_Button *,void *)122 inline void ObjectEditor::cb_up_i(Fl_Button*, void*) {
123 MP->MoveUp();
124 }
cb_up(Fl_Button * o,void * v)125 void ObjectEditor::cb_up(Fl_Button* o, void* v) {
126 ((ObjectEditor*)(o->parent()->parent()->user_data()))->cb_up_i(o,v);
127 }
128
cb__i(Fl_Button *,void *)129 inline void ObjectEditor::cb__i(Fl_Button*, void*) {
130 MP->MoveLeft();
131 }
cb_(Fl_Button * o,void * v)132 void ObjectEditor::cb_(Fl_Button* o, void* v) {
133 ((ObjectEditor*)(o->parent()->parent()->user_data()))->cb__i(o,v);
134 }
135
cb_1_i(Fl_Button *,void *)136 inline void ObjectEditor::cb_1_i(Fl_Button*, void*) {
137 MP->ZoomIn();
138 }
cb_1(Fl_Button * o,void * v)139 void ObjectEditor::cb_1(Fl_Button* o, void* v) {
140 ((ObjectEditor*)(o->parent()->parent()->user_data()))->cb_1_i(o,v);
141 }
142
cb_2_i(Fl_Button *,void *)143 inline void ObjectEditor::cb_2_i(Fl_Button*, void*) {
144 MP->ZoomOut();
145 }
cb_2(Fl_Button * o,void * v)146 void ObjectEditor::cb_2(Fl_Button* o, void* v) {
147 ((ObjectEditor*)(o->parent()->parent()->user_data()))->cb_2_i(o,v);
148 }
149
cb_3_i(Fl_Button *,void *)150 inline void ObjectEditor::cb_3_i(Fl_Button*, void*) {
151 MP->MoveRight();
152 }
cb_3(Fl_Button * o,void * v)153 void ObjectEditor::cb_3(Fl_Button* o, void* v) {
154 ((ObjectEditor*)(o->parent()->parent()->user_data()))->cb_3_i(o,v);
155 }
156
cb_down_i(Fl_Button *,void *)157 inline void ObjectEditor::cb_down_i(Fl_Button*, void*) {
158 MP->MoveDown();
159 }
cb_down(Fl_Button * o,void * v)160 void ObjectEditor::cb_down(Fl_Button* o, void* v) {
161 ((ObjectEditor*)(o->parent()->parent()->user_data()))->cb_down_i(o,v);
162 }
163
cb_redraw_i(Fl_Button *,void *)164 inline void ObjectEditor::cb_redraw_i(Fl_Button*, void*) {
165 MP->CalcImage();
166 MP->redraw();
167 MP->CheckUpdate();
168 }
cb_redraw(Fl_Button * o,void * v)169 void ObjectEditor::cb_redraw(Fl_Button* o, void* v) {
170 ((ObjectEditor*)(o->parent()->user_data()))->cb_redraw_i(o,v);
171 }
172
cb_p_re_i(Fl_Value_Input * o,void *)173 inline void ObjectEditor::cb_p_re_i(Fl_Value_Input* o, void*) {
174 MP->p(paramscroll->value()-1, 0, VD(o));
175 frac.p[paramscroll->value()-1][0] = VD(o);
176 //cout << paramscroll->value() << endl;
177 }
cb_p_re(Fl_Value_Input * o,void * v)178 void ObjectEditor::cb_p_re(Fl_Value_Input* o, void* v) {
179 ((ObjectEditor*)(o->parent()->parent()->user_data()))->cb_p_re_i(o,v);
180 }
181
cb_p_i_i(Fl_Value_Input * o,void *)182 inline void ObjectEditor::cb_p_i_i(Fl_Value_Input* o, void*) {
183 MP->p(paramscroll->value()-1, 1, VD(o));
184 frac.p[paramscroll->value()-1][1] = VD(o);
185 }
cb_p_i(Fl_Value_Input * o,void * v)186 void ObjectEditor::cb_p_i(Fl_Value_Input* o, void* v) {
187 ((ObjectEditor*)(o->parent()->parent()->user_data()))->cb_p_i_i(o,v);
188 }
189
cb_p_j_i(Fl_Value_Input * o,void *)190 inline void ObjectEditor::cb_p_j_i(Fl_Value_Input* o, void*) {
191 MP->p(paramscroll->value()-1, 2, VD(o));
192 frac.p[paramscroll->value()-1][2] = VD(o);
193 }
cb_p_j(Fl_Value_Input * o,void * v)194 void ObjectEditor::cb_p_j(Fl_Value_Input* o, void* v) {
195 ((ObjectEditor*)(o->parent()->parent()->user_data()))->cb_p_j_i(o,v);
196 }
197
cb_p_k_i(Fl_Value_Input * o,void *)198 inline void ObjectEditor::cb_p_k_i(Fl_Value_Input* o, void*) {
199 MP->p(paramscroll->value()-1, 3, VD(o));
200 frac.p[paramscroll->value()-1][3] = VD(o);
201 }
cb_p_k(Fl_Value_Input * o,void * v)202 void ObjectEditor::cb_p_k(Fl_Value_Input* o, void* v) {
203 ((ObjectEditor*)(o->parent()->parent()->user_data()))->cb_p_k_i(o,v);
204 }
205
ObjectEditor(int X,int Y,int W,int H,const char * label)206 ObjectEditor::ObjectEditor(int X, int Y, int W, int H, const char *label) : Fl_Group(X, Y, W, H, label) {
207 ChildWindow* w;
208 { ChildWindow* o = win = new ChildWindow(416, 216);
209 w = o;
210 o->user_data((void*)(this));
211 { Fl_Value_Input* o = maxiter = new Fl_Value_Input(10, 35, 60, 20, "Max.\nIteration");
212 o->tooltip("Highest number of iterations done.");
213 o->labelsize(12);
214 o->minimum(1);
215 o->maximum(1e+20);
216 o->step(1);
217 o->textsize(12);
218 o->callback((Fl_Callback*)cb_maxiter);
219 o->align(FL_ALIGN_TOP_LEFT);
220 }
221 { Fl_Value_Input* o = lvalue = new Fl_Value_Input(75, 35, 95, 20, "4th-dim.\nIntersection");
222 o->tooltip("The constant value for the 4th part of a quaternion.");
223 o->labelsize(12);
224 o->minimum(-1e+20);
225 o->maximum(1e+20);
226 o->textsize(12);
227 o->callback((Fl_Callback*)cb_lvalue);
228 o->align(FL_ALIGN_TOP_LEFT);
229 }
230 { Fl_Value_Input* o = bailout = new Fl_Value_Input(175, 35, 95, 20, "Bailout");
231 o->tooltip("If this value is exceeded, iteration is ready.");
232 o->labelsize(12);
233 o->maximum(1e+20);
234 o->textsize(12);
235 o->callback((Fl_Callback*)cb_bailout);
236 o->align(FL_ALIGN_TOP_LEFT);
237 }
238 { Fl_Choice* o = formula = new Fl_Choice(65, 65, 205, 30, "Iteration \nFormula ");
239 o->tooltip("The formula that gets iterated.");
240 o->down_box(FL_BORDER_BOX);
241 o->labelsize(12);
242 o->textsize(12);
243 o->callback((Fl_Callback*)cb_formula);
244 o->menu(menu_formula);
245 }
246 { Fl_Value_Input* o = cre = new Fl_Value_Input(10, 125, 95, 20, "c (1, i, j, k parts)");
247 o->tooltip("Real part of c.");
248 o->labelsize(12);
249 o->minimum(-1e+20);
250 o->maximum(1e+20);
251 o->textsize(12);
252 o->callback((Fl_Callback*)cb_cre);
253 o->align(FL_ALIGN_TOP_LEFT);
254 }
255 { Fl_Value_Input* o = ci = new Fl_Value_Input(10, 145, 95, 20, "value:");
256 o->tooltip("1st imaginary (i) part of c.");
257 o->labeltype(FL_NO_LABEL);
258 o->labelsize(12);
259 o->minimum(-1e+20);
260 o->maximum(1e+20);
261 o->textsize(12);
262 o->callback((Fl_Callback*)cb_ci);
263 }
264 { Fl_Value_Input* o = cj = new Fl_Value_Input(10, 165, 95, 20, "value:");
265 o->tooltip("2nd imaginary (j) part of c.");
266 o->labeltype(FL_NO_LABEL);
267 o->labelsize(12);
268 o->minimum(-1e+20);
269 o->maximum(1e+20);
270 o->textsize(12);
271 o->callback((Fl_Callback*)cb_cj);
272 }
273 { Fl_Value_Input* o = ck = new Fl_Value_Input(10, 185, 95, 19, "value:");
274 o->tooltip("3rd imaginary part (k) of c.");
275 o->labeltype(FL_NO_LABEL);
276 o->labelsize(12);
277 o->minimum(-1e+20);
278 o->maximum(1e+20);
279 o->textsize(12);
280 o->callback((Fl_Callback*)cb_ck);
281 }
282 { Fl_Group* o = paramgroup = new Fl_Group(280, 20, 115, 125);
283 { Fl_Box* o = new Fl_Box(285, 20, 105, 125, "Parameter");
284 o->box(FL_UP_BOX);
285 o->labelsize(12);
286 o->align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE);
287 }
288 { Fl_Scrollbar* o = paramscroll = new Fl_Scrollbar(290, 120, 95, 15);
289 o->type(1);
290 }
291 o->end();
292 }
293 { Fl_Group* o = new Fl_Group(225, 165, 80, 40);
294 { Fl_Button* o = new Fl_Button(225, 165, 40, 20, "up");
295 o->tooltip("Navigation in Mandelbrot Preview.");
296 o->shortcut(0x80069);
297 o->labelsize(12);
298 o->callback((Fl_Callback*)cb_up);
299 }
300 { Fl_Button* o = new Fl_Button(225, 185, 20, 20, "<");
301 o->tooltip("Navigation in Mandelbrot Preview: to the left.");
302 o->shortcut(0x8006a);
303 o->labelsize(12);
304 o->callback((Fl_Callback*)cb_);
305 }
306 { Fl_Button* o = new Fl_Button(245, 185, 20, 20, "+");
307 o->tooltip("Zoom In.");
308 o->shortcut(0x2b);
309 o->labelsize(12);
310 o->callback((Fl_Callback*)cb_1);
311 }
312 { Fl_Button* o = new Fl_Button(265, 185, 20, 20, "-");
313 o->tooltip("Zoom out.");
314 o->shortcut(0x2d);
315 o->labelsize(12);
316 o->callback((Fl_Callback*)cb_2);
317 }
318 { Fl_Button* o = new Fl_Button(285, 185, 20, 20, ">");
319 o->tooltip("Navigation in Mandelbrot Preview: to the right.");
320 o->shortcut(0x8006c);
321 o->labelsize(12);
322 o->callback((Fl_Callback*)cb_3);
323 }
324 { Fl_Button* o = new Fl_Button(265, 165, 40, 20, "down");
325 o->tooltip("Navigation in Mandelbrot Preview.");
326 o->shortcut(0x8006b);
327 o->labelsize(12);
328 o->callback((Fl_Callback*)cb_down);
329 }
330 o->end();
331 }
332 { Fl_Button* o = redraw = new Fl_Button(225, 125, 45, 20, "&redraw");
333 o->tooltip("Redraws the Mandebrot Preview.");
334 o->shortcut(0x80072);
335 o->labelsize(12);
336 o->callback((Fl_Callback*)cb_redraw);
337 o->deactivate();
338 }
339 { MandelPreview* o = MP = new MandelPreview(110, 125, 110, 80, "label");
340 o->tooltip("Mandelbrot preview:\nfor easy selection of c (real- and i- part)\nRed frame: \
341 Redraw required.");
342 o->box(FL_EMBOSSED_FRAME);
343 o->labeltype(FL_NO_LABEL);
344 o->labelsize(12);
345 }
346 { Fl_Group* o = paramgroup2 = new Fl_Group(290, 20, 95, 100);
347 { Fl_Value_Input* o = p_re = new Fl_Value_Input(290, 35, 95, 20, "p1");
348 o->tooltip("Real part of p1.");
349 o->labelsize(12);
350 o->minimum(-1e+20);
351 o->maximum(1e+20);
352 o->textsize(12);
353 o->callback((Fl_Callback*)cb_p_re);
354 o->align(FL_ALIGN_TOP_RIGHT);
355 }
356 { Fl_Value_Input* o = p_i = new Fl_Value_Input(290, 56, 95, 20, "value:");
357 o->tooltip("1st imaginary (i) part of p1.");
358 o->labeltype(FL_NO_LABEL);
359 o->labelsize(12);
360 o->minimum(-1e+20);
361 o->maximum(1e+20);
362 o->textsize(12);
363 o->callback((Fl_Callback*)cb_p_i);
364 }
365 { Fl_Value_Input* o = p_j = new Fl_Value_Input(290, 76, 95, 20, "value:");
366 o->tooltip("2nd imaginary (j) part of p1.");
367 o->labeltype(FL_NO_LABEL);
368 o->labelsize(12);
369 o->minimum(-1e+20);
370 o->maximum(1e+20);
371 o->textsize(12);
372 o->callback((Fl_Callback*)cb_p_j);
373 }
374 { Fl_Value_Input* o = p_k = new Fl_Value_Input(290, 96, 95, 19, "value:");
375 o->tooltip("3rd imaginary (k) part of p1.");
376 o->labeltype(FL_NO_LABEL);
377 o->labelsize(12);
378 o->minimum(-1e+20);
379 o->maximum(1e+20);
380 o->textsize(12);
381 o->callback((Fl_Callback*)cb_p_k);
382 }
383 o->end();
384 }
385 o->clear_border();
386 o->end();
387 }
388 MP->SetInputs(cre, ci, redraw);
389 end(); // VERY IMPORTANT!
390 win->position(X+2, Y+2);
391 // DON'T delete win in destructor (or elsewhere)
392 // it's automatically deleted by Fl_Group
393 }
394
set(const frac_cpp & f)395 void ObjectEditor::set(const frac_cpp& f) {
396 frac = f;
397 maxiter->value(f.maxiter); maxiter->do_callback();
398 lvalue->value(f.lvalue); lvalue->do_callback();
399 bailout->value(f.bailout); bailout->do_callback();
400 formula->value(f.formula); formula->do_callback(); // Also calls formula_changed()
401 cre->value(f.c[0]); cre->do_callback();
402 ci->value(f.c[1]); ci->do_callback();
403 cj->value(f.c[2]); cj->do_callback();
404 ck->value(f.c[3]); ck->do_callback();
405 for (int j=0; j<4; j++) for (int i=0; i<4; i++) MP->p(j, i, f.p[j][i]);
406 MP->CalcImage(); MP->CheckUpdate();
407 }
408
get(frac_cpp & f)409 void ObjectEditor::get(frac_cpp& f) {
410 f = frac;
411 return;
412 }
413
formula_changed()414 void ObjectEditor::formula_changed() {
415 int pno = 0;
416 switch (frac.formula) {
417 case 4: pno = 1; break;
418 default: pno = 0; break;
419 }
420
421 if (pno == 0) {
422 paramgroup->hide();
423 paramgroup2->hide();
424 }
425 else {
426 paramgroup->show();
427 paramgroup2->show();
428 }
429
430 paramscroll->scrollvalue(1,1,1,pno);
431 if (pno != 0) paramscroll_changed();
432 }
433
paramscroll_changed()434 void ObjectEditor::paramscroll_changed() {
435 int i = paramscroll->value();
436 p_re->value(frac.p[i-1][0]);
437 p_i->value(frac.p[i-1][1]);
438 p_j->value(frac.p[i-1][2]);
439 p_k->value(frac.p[i-1][3]);
440 }
441
deactiv()442 void ObjectEditor::deactiv() {
443 maxiter->deactivate();
444 lvalue->deactivate();
445 bailout->deactivate();
446 formula->deactivate();
447 cre->deactivate();
448 ci->deactivate();
449 cj->deactivate();
450 ck->deactivate();
451 MP->deactivate();
452 paramgroup2->deactivate();
453 }
454