source: rtems-graphics-toolkit/fltk-1.1.10/test/mandelbrot.cxx @ 513eea1

Last change on this file since 513eea1 was 513eea1, checked in by Joel Sherrill <joel.sherrill@…>, on 01/09/10 at 22:43:24

2010-01-08 Joel Sherrill <joel.sherrill@…>

fltk 1.1.10. imported

  • ORIGIN: Updated.
  • Property mode set to 100644
File size: 5.0 KB
Line 
1//
2// "$Id$"
3//
4// Mandelbrot set demo for the Fast Light Tool Kit (FLTK).
5//
6// Copyright 1998-2005 by Bill Spitzak and others.
7//
8// This library is free software; you can redistribute it and/or
9// modify it under the terms of the GNU Library General Public
10// License as published by the Free Software Foundation; either
11// version 2 of the License, or (at your option) any later version.
12//
13// This library is distributed in the hope that it will be useful,
14// but WITHOUT ANY WARRANTY; without even the implied warranty of
15// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16// Library General Public License for more details.
17//
18// You should have received a copy of the GNU Library General Public
19// License along with this library; if not, write to the Free Software
20// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21// USA.
22//
23// Please report all bugs and problems on the following page:
24//
25//     http://www.fltk.org/str.php
26//
27
28#include "mandelbrot_ui.h"
29#include <FL/fl_draw.H>
30#include <stdio.h>
31#include <stdlib.h>
32
33Drawing_Window mbrot;
34Drawing_Window jbrot;
35
36void idle(void*) {
37  if (!mbrot.d->idle() && !(jbrot.d && jbrot.d->idle())) Fl::remove_idle(idle);
38}
39
40void set_idle() {
41  Fl::add_idle(idle);
42}
43
44static void window_callback(Fl_Widget*, void*) {exit(0);}
45
46int main(int argc, char **argv) {
47  mbrot.make_window();
48  mbrot.d->X = -.75;
49  mbrot.d->scale = 2.5;
50  mbrot.update_label();
51  int i = 0;
52  if (Fl::args(argc,argv,i) < argc) Fl::fatal(Fl::help);
53  Fl::visual(FL_RGB);
54  mbrot.window->callback(window_callback);
55  mbrot.window->show(argc,argv);
56  Fl::run();
57  return 0;
58}
59
60void Drawing_Window::update_label() {
61  char buffer[128];
62  sprintf(buffer, "%+.10f", d->X); x_input->value(buffer);
63  sprintf(buffer, "%+.10f", d->Y); y_input->value(buffer);
64  sprintf(buffer, "%.2g", d->scale); w_input->value(buffer);
65}
66
67void Drawing_Area::draw() {
68  draw_box();
69  drawn = 0;
70  set_idle();
71}
72
73int Drawing_Area::idle() {
74  if (!window()->visible()) return 0;
75  if (drawn < nextline) {
76    window()->make_current();
77    int yy = drawn+y()+4;
78    if (yy >= sy && yy <= sy+sh) erase_box();
79    fl_draw_image_mono(buffer+drawn*W,x()+3,yy,W,1,1,W);
80    drawn++;
81    return 1;
82  }
83  if (nextline < H) {
84    if (!buffer) buffer = new uchar[W*H];
85    double yy = Y+(H/2-nextline)*scale/W;
86    double yi = yy; if (julia) yy = jY;
87    uchar *p = buffer+nextline*W;
88    for (int xi = 0; xi < W; xi++) {
89      double xx = X+(xi-W/2)*scale/W;
90      double wx = xx; double wy = yi;
91      if (julia) xx = jX;
92      for (int i=0; ; i++) {
93        if (i >= iterations) {*p = 0; break;}
94        double t = wx*wx - wy*wy + xx;
95        wy = 2*wx*wy + yy;
96        wx = t;
97        if (wx*wx + wy*wy > 4) {
98          wx = t = 1-double(i)/(1<<10);
99          if (t <= 0) t = 0; else for (i=brightness; i--;) t*=wx;
100          *p = 255-int(254*t);
101          break;
102        }
103      }
104      p++;
105    }
106    nextline++;
107    return nextline < H;
108  }
109  return 0;
110}
111
112void Drawing_Area::erase_box() {
113  window()->make_current();
114  fl_overlay_clear();
115}
116
117int Drawing_Area::handle(int event) {
118  static int ix, iy;
119  static int dragged;
120  static int button;
121  int x2,y2;
122  switch (event) {
123  case FL_PUSH:
124    erase_box();
125    ix = Fl::event_x(); if (ix<x()) ix=x(); if (ix>=x()+w()) ix=x()+w()-1;
126    iy = Fl::event_y(); if (iy<y()) iy=y(); if (iy>=y()+h()) iy=y()+h()-1;
127    dragged = 0;
128    button = Fl::event_button();
129    return 1;
130  case FL_DRAG:
131    dragged = 1;
132    erase_box();
133    x2 = Fl::event_x(); if (x2<x()) x2=x(); if (x2>=x()+w()) x2=x()+w()-1;
134    y2 = Fl::event_y(); if (y2<y()) y2=y(); if (y2>=y()+h()) y2=y()+h()-1;
135    if (button != 1) {ix = x2; iy = y2; return 1;}
136    if (ix < x2) {sx = ix; sw = x2-ix;} else {sx = x2; sw = ix-x2;}
137    if (iy < y2) {sy = iy; sh = y2-iy;} else {sy = y2; sh = iy-y2;}
138    window()->make_current();
139    fl_overlay_rect(sx,sy,sw,sh);
140    return 1;
141  case FL_RELEASE:
142    if (button == 1) {
143      erase_box();
144      if (dragged && sw > 3 && sh > 3) {
145        X = X + (sx+sw/2-x()-W/2)*scale/W;
146        Y = Y + (-sy-sh/2+y()+H/2)*scale/W;
147        scale = sw*scale/W;
148      } else if (!dragged) {
149        scale = 2*scale;
150        if (julia) {
151          if (scale >= 4) {
152            scale = 4;
153            X = Y = 0;
154          }
155        } else {
156          if (scale >= 2.5) {
157            scale = 2.5;
158            X = -.75;
159            Y = 0;
160          }
161        }
162      } else return 1;
163      ((Drawing_Window*)(user_data()))->update_label();
164      new_display();
165    } else if (!julia) {
166      if (!jbrot.d) {
167        jbrot.make_window();
168        jbrot.d->julia = 1;
169        jbrot.d->X = 0;
170        jbrot.d->Y = 0;
171        jbrot.d->scale = 4;
172        jbrot.update_label();
173      }
174      jbrot.d->jX = X + (ix-x()-W/2)*scale/W;
175      jbrot.d->jY = Y + (H/2-iy+y())*scale/W;
176      static char s[128];
177      sprintf(s, "Julia %.7f %.7f",jbrot.d->jX,jbrot.d->jY);
178      jbrot.window->label(s);
179      jbrot.window->show();
180      jbrot.d->new_display();
181    }
182    return 1;
183  }
184  return 0;
185}
186
187void Drawing_Area::new_display() {
188  drawn = nextline = 0;
189  set_idle();
190}
191
192void Drawing_Area::resize(int XX,int YY,int WW,int HH) {
193  if (WW != w() || HH != h()) {
194    W = WW-6;
195    H = HH-8;
196    if (buffer) {delete[] buffer; buffer = 0; new_display();}
197  }
198  Fl_Box::resize(XX,YY,WW,HH);
199}
200
201//
202// End of "$Id$".
203//
Note: See TracBrowser for help on using the repository browser.