1 /*
2 * Author: spencer jackson 2014
3 * ssjackson71@gmail.com
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (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 General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 *
20 */
21
22
23 #ifndef FFF_SCOPE_H
24 #define FFF_SCOPE_H
25
26
27 #include <FL/Fl_Widget.H>
28 #include <FL/Fl.H>
29 #include <valarray>
30 #include <string>
31 #include <cairo.h>
32
33 //avtk drawing method (adapted)
default_scope_drawing(cairo_t * cr,float * data,unsigned short start)34 static void default_scope_drawing(cairo_t *cr,float *data,unsigned short start)
35 {
36 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
37 cairo_set_line_width(cr,1);
38 cairo_set_miter_limit(cr,4);
39 cairo_set_source_rgb(cr,0,1,0);
40 cairo_new_path(cr);
41
42 cairo_move_to(cr,100,100*data[start]);
43 for (int i=1; i<100; i++)
44 {
45 cairo_line_to(cr,100-i,100*data[(start-i)&0x07FF]);
46 }
47 cairo_stroke(cr);
48 };
49
50 namespace ffffltk
51 {
52
53 static void scope_callback(void* handle);
54
55 class Scope: public Fl_Widget
56 {
57 public:
58 Scope(int _x, int _y, int _w, int _h, const char *_label = ""):
Fl_Widget(_x,_y,_w,_h,_label)59 Fl_Widget(_x, _y, _w, _h, _label)
60 {
61 x = _x;
62 y = _y;
63 w = _w;
64 h = _h;
65
66 label = _label;
67
68 drawing_w = 100;
69 drawing_h = 100;
70 drawing_f = &default_scope_drawing;
71
72 average = false;
73 avg = 0;
74 p = 0;
75 nvals = 0;
76 min_val = 0;
77 max_val = 1;
78 for(int i=0; i<2048; i++)
79 data[i] = 0;
80 Fl::add_timeout(.10,scope_callback,this);
81 }
82
~Scope()83 ~Scope()
84 {
85 Fl::remove_timeout(scope_callback);
86 }
87
88 bool highlight;
89 int x, y, w, h;
90 const char* label;
91
92 int drawing_w;
93 int drawing_h;
94 void (*drawing_f)(cairo_t*,float*, unsigned short);//pointer to draw function
95
96 float data[2048];
97 int min_val;
98 int max_val;
99 bool average;
100
101 float avg;
102 int p;
103 int nvals;
104
push_val(float val)105 void push_val(float val)
106 {
107 if(average)
108 {
109 avg += val;
110 nvals++;
111 }
112 else
113 {
114 data[p++] = val;
115 p&=0x07FF;
116 }
117 }
118
push_avg()119 void push_avg()
120 {
121 avg/= (double)nvals;
122 data[p++] = avg;
123 p&=0x07FF;
124 nvals = 0;
125 }
126
draw()127 void draw()
128 {
129 if (damage() & FL_DAMAGE_ALL)
130 {
131 cairo_t *cr = Fl::cairo_cc();
132
133 cairo_save( cr );
134
135 //calcluate scale and centering
136 double scalex,
137 scaley,
138 shiftx=0,
139 shifty=0;
140 scalex = w/(double)drawing_w;
141 scaley = h/(double)drawing_h;
142 {
143 if(scalex > scaley)
144 {
145 scalex = scaley;
146 shiftx = (w - scalex*drawing_w)/2.f;
147 }
148 else
149 {
150 scaley = scalex;
151 shifty = h - scaley*drawing_h;
152 }
153 }
154 //move to position in the window
155 cairo_translate(cr,x+shiftx,y+shifty);
156 //scale the drawing
157 cairo_scale(cr,scalex,scaley);
158 //call the draw function
159 if(drawing_f) drawing_f(cr,data,p);
160 else default_scope_drawing(cr,data,p);
161
162 cairo_restore( cr );
163 }
164 }
165
resize(int X,int Y,int W,int H)166 void resize(int X, int Y, int W, int H)
167 {
168 Fl_Widget::resize(X,Y,W,H);
169 x = X;
170 y = Y;
171 w = W;
172 h = H;
173 redraw();
174 }
175
176 /*
177 int handle(int event)
178 {
179 return 0;
180
181 switch(event)
182 {
183 case FL_PUSH:
184 highlight = 0;
185 redraw();
186 return 1;
187 case FL_DRAG: {
188 int t = Fl::event_inside(this);
189 if (t != highlight) {
190 redraw();
191 }
192 }
193 return 1;
194 case FL_SHORTCUT:
195 if ( test_shortcut() )
196 {
197 do_callback();
198 return 1;
199 }
200 return 0;
201 default:
202 return Fl_Widget::handle(event);
203 }
204 }
205 */
206 };
207
scope_callback(void * handle)208 static void scope_callback(void* handle)
209 {
210 Scope* scope = (Scope*)handle;
211 Fl::repeat_timeout(.10,scope_callback,handle);
212 if(scope->average)
213 {
214 scope->push_avg();
215 }
216 scope->redraw();
217 };
218
219 } // ffffltk
220
221 #endif // FFF_SCOPE_H
222
223