2 /*******************************************************************************/
3 /* Copyright (C) 2008 Jonathan Moore Liles */
5 /* This program is free software; you can redistribute it and/or modify it */
6 /* under the terms of the GNU General Public License as published by the */
7 /* Free Software Foundation; either version 2 of the License, or (at your */
8 /* option) any later version. */
10 /* This program is distributed in the hope that it will be useful, but WITHOUT */
11 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
12 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */
15 /* You should have received a copy of the GNU General Public License along */
16 /* with This program; see the file COPYING. If not,write to the Free Software */
17 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /*******************************************************************************/
25 // #include <FL/fl_draw.H>
27 /* 2D Panner widget. Supports various multichannel configurations. */
29 Panner::Point *Panner::drag;
31 /* multichannel layouts, in degrees */
32 int Panner::_configs[][12] =
34 /* none, error condition? */
36 /* mono, panner disabled */
45 { FL, FR, RL, RR, C },
49 { FL, FR, RL, RR, C, L, R },
54 #define BP fl_begin_polygon()
55 #define EP fl_end_polygon()
56 #define BCP fl_begin_complex_polygon()
57 #define ECP fl_end_complex_polygon()
58 #define BL fl_begin_line()
59 #define EL fl_end_line()
60 #define BC fl_begin_loop()
61 #define EC fl_end_loop()
62 #define vv(x,y) fl_vertex(x,y)
64 static void draw_speaker ( Fl_Color col )
68 BP; vv(0.2,0.4); vv(0.6,0.4); vv(0.6,-0.4); vv(0.2,-0.4); EP;
69 BP; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EP;
71 fl_color( fl_darker( col ) );
73 BC; vv(0.2,0.4); vv(0.6,0.4); vv(0.6,-0.4); vv(0.2,-0.4); EC;
74 BC; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EC;
78 /** set X, Y, W, and H to the bounding box of point /p/ in screen coords */
80 Panner::point_bbox ( const Point *p, int *X, int *Y, int *W, int *H ) const
84 bbox( tx, ty, tw, th );
86 const float PW = pw();
87 const float PH = ph();
96 *X = tx + ((tw / 2) * px + (tw / 2));
97 *Y = ty + ((th / 2) * py + (th / 2));
104 Panner::event_point ( void )
106 for ( int i = _ins; i--; )
110 Point *p = &_points[ i ];
112 point_bbox( p, &px, &py, &pw, &ph );
114 // printf( "%d, %d -- %d %d %d %d\n", Fl::event_x(), Fl::event_y(), px, py, pw, ph );
116 if ( Fl::event_inside( px, py, pw, ph ) )
125 Panner::draw_the_box ( int tx, int ty, int tw, int th )
129 fl_line_style( FL_SOLID, 2 );
136 if ( Fl::belowmouse() == this )
139 c1 = fl_darker( fl_darker( FL_RED ) );
151 for ( int i = iter; i--; )
155 fl_arc( tx + (i * (tw / iter)) / 2, ty + (i * (th / iter)) / 2, tw - (i * (tw / iter)), th - (i * ( th / iter )), 0, 360 );
160 /* ((float)tw / iter) / 2, */
163 c = fl_color_average( c1, c2, (float)i / iter);
167 fl_line_style( FL_SOLID, 0 );
172 Panner::draw ( void )
176 bbox( tx, ty, tw, th );
178 fl_push_clip( tx, ty, tw, th );
190 fl_font( FL_HELVETICA, 12 );
191 fl_draw( "(bypass)", x(), y(), w(), h(), FL_ALIGN_CENTER );
201 if ( damage() & FL_DAMAGE_ALL )
202 draw_the_box( tx, ty, tw, th );
204 fl_line_style( FL_SOLID, 2 );
206 // fl_color( FL_RED );
208 fl_color( FL_WHITE );
210 /* fl_arc( tx, ty, tw, th, 0, 360 ); */
212 if ( _configs[ _outs ][0] >= 0 )
214 for ( int i = _outs; i--; )
216 int a = _configs[ _outs ][ i ];
218 Point p( 1.2f, (float)a );
226 const int bx = tx + ((tw / 2) * px + (tw / 2));
227 const int by = ty + ((th / 2) * py + (th / 2));
229 fl_translate( bx, by );
237 draw_speaker( FL_WHITE );
246 /* ensure that points are drawn *inside* the circle */
248 for ( int i = _ins; i--; )
250 Point *p = &_points[ i ];
252 Fl_Color c = (Fl_Color)(10 + i);
255 point_bbox( p, &px, &py, &pw, &ph );
261 const float S = ( 0.5 + ( 1.0f - p->d ) );
265 fl_push_clip( px - ( po * 12 ),
267 pw + ( po * 24 ), ph + (po * 24 ));
269 if ( damage() & FL_DAMAGE_EXPOSE )
270 draw_the_box( tx, ty, tw, th );
272 fl_color( FL_WHITE );
278 fl_pie( px, py, pw, ph, 0, 360 );
281 fl_color( c = fl_darker( c ) );
282 // fl_color_alpha( c = fl_darker( c ), 0.5 );
284 // fl_arc( cr, px, py, pw + po * 1, 0, 360 );
285 fl_arc( px - po, py - po, pw + ( po * 2 ), ph + ( po * 2 ), 0, 360 );
287 if ( Fl::belowmouse() == this )
289 fl_color( c = fl_darker( c ) );
291 // fl_color_alpha( c = fl_darker( c ), 0.5 );
292 fl_arc( px - ( po * 2 ), py - ( po * 2 ), pw + ( po * 4 ), ph + ( po * 4 ), 0, 360 );
293 /* fl_arc( cr, px, py, pw + po * 1, 0, 360 ); */
295 fl_color( c = fl_darker( c ) );
297 // fl_color_alpha( c = fl_darker( c ), 0.5 );
298 fl_arc( px - ( po * 4 ), py - ( po * 4 ), pw + ( po * 8 ), ph + (po * 8 ), 0, 360 );
299 /* fl_arc( cr, px, py, pw + po * 1, 0, 360 ); */
307 snprintf( pat, 4, "%d", i + 1 );
309 fl_color( FL_BLACK );
310 fl_font( FL_HELVETICA, ph + 2 );
311 fl_draw( pat, px + 1, py + 1, pw - 1, ph - 1, FL_ALIGN_CENTER );
315 /* fl_color( FL_WHITE ); */
316 /* fl_line( bx + pw() / 2, by + ph() / 2, tx + (tw / 2), ty + (th / 2) ); */
321 fl_line_style( FL_SOLID, 0 );
326 /* return the current gain setting for the path in/out */
328 Panner::point( int i )
330 return &_points[ i ];
334 Panner::handle ( int m )
336 int r = Fl_Widget::handle( m );
346 if ( Fl::event_button2() )
348 _bypassed = ! _bypassed;
353 if ( Fl::event_button1() )
354 drag = event_point();
359 if ( Fl::event_button1() && drag )
370 /* TODO: place point on opposite face of sphere */
377 /* else if ( Fl::event_button1() && ( drag = event_point() ) ) */
381 float X = Fl::event_x() - x();
382 float Y = Fl::event_y() - y();
385 bbox( tx, ty, tw, th );
387 /* if ( _outs < 3 ) */
388 /* drag->angle( (float)(X / (tw / 2)) - 1.0f, 0.0f ); */
390 drag->angle( (float)(X / (tw / 2)) - 1.0f, (float)(Y / (th / 2)) - 1.0f );
392 if ( when() & FL_WHEN_CHANGED )
395 damage(FL_DAMAGE_EXPOSE);