1 /*
2  * Author: Harry van Haaren 2013
3  *         harryhaaren@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 3 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, see <http://www.gnu.org/licenses/>.
17  */
18 
19 
20 #ifndef AVTK_REVERB_H
21 #define AVTK_REVERB_H
22 
23 #include <FL/Fl_Slider.H>
24 
25 namespace Avtk
26 {
27 
28 class Reverb : public Fl_Slider
29 {
30 public:
31 	Reverb(int _x, int _y, int _w, int _h, const char *_label =0):
Fl_Slider(_x,_y,_w,_h)32 		Fl_Slider(_x, _y, _w, _h)
33 	{
34 		copy_label(_label);
35 		x = _x;
36 		y = _y;
37 		w = _w;
38 		h = _h;
39 
40 		amp = 0.5;
41 		s   = 0.5;
42 		damp= 0.5;
43 
44 		active = false;
45 
46 		highlight = false;
47 		mouseOver = false;
48 	}
49 
size(float v)50 	void size(float v)
51 	{
52 		s = v;
53 		redraw();
54 	}
wet(float v)55 	void wet(float v)
56 	{
57 		amp = v;
58 		redraw();
59 	}
damping(float v)60 	void damping(float v)
61 	{
62 		damp = v;
63 		redraw();
64 	}
65 
size()66 	float size()
67 	{
68 		return s;
69 	}
wet()70 	float wet ()
71 	{
72 		return amp;
73 	}
damping()74 	float damping()
75 	{
76 		return damp;
77 	}
78 
getActive()79 	bool getActive()
80 	{
81 		return active;
82 	}
setActive(bool a)83 	void setActive(bool a)
84 	{
85 		active = a;
86 		redraw();
87 	}
88 
89 	float s;
90 	float amp;
91 	float damp;
92 
93 	bool active;
94 
95 	bool mouseOver;
96 	bool highlight;
97 	int x, y, w, h;
98 
draw()99 	void draw()
100 	{
101 		if (damage() & FL_DAMAGE_ALL) {
102 			cairo_t *cr = Fl::cairo_cc();
103 
104 			cairo_save( cr );
105 
106 			// graph
107 			cairo_rectangle( cr, x, y, w, h );
108 			cairo_set_source_rgb( cr,28 / 255.f,  28 / 255.f ,  28 / 255.f  );
109 			cairo_fill(cr);
110 
111 
112 			// set up dashed lines, 1 px off, 1 px on
113 			double dashes[1];
114 			dashes[0] = 2.0;
115 
116 			cairo_set_dash ( cr, dashes, 1, 0.0);
117 
118 			// loop over each 2nd line, drawing dots
119 			cairo_set_line_width(cr, 1.0);
120 			cairo_set_source_rgb(cr, 0.4,0.4,0.4);
121 			for ( int i = 0; i < 4; i++ ) {
122 				cairo_move_to( cr, x + ((w / 4.f)*i), y );
123 				cairo_line_to( cr, x + ((w / 4.f)*i), y + h );
124 			}
125 			for ( int i = 0; i < 4; i++ ) {
126 				cairo_move_to( cr, x    , y + ((h / 4.f)*i) );
127 				cairo_line_to( cr, x + w, y + ((h / 4.f)*i) );
128 			}
129 			cairo_set_source_rgba( cr,  66 / 255.f,  66 / 255.f ,  66 / 255.f , 0.5 );
130 			cairo_stroke(cr);
131 			cairo_set_dash ( cr, dashes, 0, 0.0);
132 
133 			// draw "damping" control
134 			cairo_move_to( cr, x+w*0.1              , y + h*0.85 - (h*0.7*amp));
135 			cairo_line_to( cr, x+w*0.1 + (w-20)*damp, y + h*0.85 - (h*0.7*amp));
136 			cairo_set_source_rgba(cr, 1.0, 0.48,   0,  1);
137 			cairo_set_line_join( cr, CAIRO_LINE_JOIN_ROUND);
138 			cairo_set_line_cap ( cr, CAIRO_LINE_CAP_ROUND);
139 			cairo_set_line_width(cr, 1.9);
140 			cairo_stroke( cr );
141 
142 			// draw reverb triangle
143 			cairo_move_to( cr, x , y + h*0.99 );
144 			cairo_line_to( cr, x + w*0.1, y + h*0.85 - (h*0.7*amp));
145 			cairo_line_to( cr, x + w*0.3+w*0.7*s, y + (h*0.99));
146 
147 			// stroke
148 			cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 0.21 );
149 			cairo_fill_preserve(cr);
150 			cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
151 			cairo_set_line_width(cr, 1.2);
152 			cairo_stroke( cr );
153 
154 			// stroke rim
155 			cairo_rectangle(cr, x, y, w, h);
156 			//cairo_set_source_rgba( cr, 0 / 255.f, 153 / 255.f , 255 / 255.f , 1 );
157 			cairo_set_source_rgba( cr,  126 / 255.f,  126 / 255.f ,  126 / 255.f , 0.8 );
158 			cairo_set_line_width(cr, 0.9);
159 			cairo_stroke( cr );
160 
161 			if ( !active ) {
162 				// big grey X
163 				cairo_set_line_width(cr, 12.0);
164 				cairo_set_source_rgba(cr, 0.0,0.0,0.0, 1.0);
165 
166 				cairo_move_to( cr, x + (3 * w / 4.f), y + ( h / 4.f ) );
167 				cairo_line_to( cr, x + (w / 4.f), y + ( 3 *h / 4.f ) );
168 
169 				cairo_move_to( cr, x + (w / 4.f), y + ( h / 4.f ) );
170 				cairo_line_to( cr, x + (3 * w / 4.f), y + ( 3 *h / 4.f ) );
171 				cairo_set_line_cap ( cr, CAIRO_LINE_CAP_BUTT);
172 				cairo_stroke( cr );
173 			}
174 
175 			cairo_restore( cr );
176 
177 			draw_label();
178 		}
179 	}
180 
resize(int X,int Y,int W,int H)181 	void resize(int X, int Y, int W, int H)
182 	{
183 		Fl_Widget::resize(X,Y,W,H);
184 		x = X;
185 		y = Y;
186 		w = W;
187 		h = H;
188 		redraw();
189 	}
190 
handle(int event)191 	int handle(int event)
192 	{
193 		switch(event) {
194 		case FL_PUSH:
195 			highlight = 1;
196 			if ( Fl::event_button() == FL_RIGHT_MOUSE ) {
197 				active = !active;
198 				redraw();
199 				do_callback();
200 			}
201 			return 1;
202 		case FL_DRAG: {
203 			int t = Fl::event_inside(this);
204 			if (t != highlight) {
205 				highlight = t;
206 				redraw();
207 			}
208 		}
209 		return 1;
210 		case FL_ENTER:
211 			mouseOver = true;
212 			redraw();
213 			return 1;
214 		case FL_LEAVE:
215 			mouseOver = false;
216 			redraw();
217 			return 1;
218 		case FL_RELEASE:
219 			if (highlight) {
220 				highlight = 0;
221 				redraw();
222 			}
223 			return 1;
224 		case FL_SHORTCUT:
225 			if ( test_shortcut() ) {
226 				do_callback();
227 				return 1;
228 			}
229 			return 0;
230 		default:
231 			return Fl_Widget::handle(event);
232 		}
233 	}
234 };
235 
236 } // Avtk
237 
238 #endif // AVTK_ADSR_H
239 
240