diff --git a/Panner.C b/Panner.C index 1af0420..9094879 100644 --- a/Panner.C +++ b/Panner.C @@ -24,16 +24,6 @@ /* 2D Panner widget. Supports various multichannel configurations. */ -enum { - NONE = -1, - R = 90, - L = 270, - C = 0, - FL = 315, - FR = 45, - RL = 225, - RR = 135, -}; /* multichannel layouts, in degrees */ int Panner::_configs[][12] = @@ -97,36 +87,41 @@ Panner::event_point ( void ) { Point *p = &_points[ i ]; - if ( Fl::event_inside( X + ((p->x * (W / 2)) + (W / 2)), - Y + ((p->y * (H / 2)) + (H / 2)), pw(), ph() ) ) + float px, py; + + p->axes( &px, &py ); + + if ( Fl::event_inside( X + ((px * (W / 2)) + (W / 2)), + Y + ((py * (H / 2)) + (H / 2)), pw(), ph() ) ) return p; + } return NULL; } /* translate angle /a/ into x/y coords and place the result in /X/ and /Y/ */ -Panner::Point -Panner::angle_to_axes ( float a ) -{ - Point p; +/* Panner::Point */ +/* Panner::angle_to_axes ( float a ) */ +/* { */ +/* Point p; */ - a -= 90; - a = 360 - a; +/* a -= 90; */ +/* a = 360 - a; */ - double A; +/* double A; */ - A = a * ( M_PI / 180 ); +/* A = a * ( M_PI / 180 ); */ - // const float r = tw / 2; +/* // const float r = tw / 2; */ - const double r = 1.0f; +/* const double r = 1.0f; */ - p.x = r * cos( A ); - p.y = -r * sin( A ); +/* p.x = r * cos( A ); */ +/* p.y = -r * sin( A ); */ - return p; -} +/* return p; */ +/* } */ void Panner::draw ( void ) @@ -166,8 +161,8 @@ Panner::draw ( void ) /* fl_arc( tx, ty, tw, th, a - 20, a + 20 ); */ /* fl_line_style( FL_SOLID, 0 ); */ - Point p = angle_to_axes( a ); -// printf( "%d: %f, %f\n", i, p.x, p.y ); +/* Point p = angle_to_axes( a ); */ +/* // printf( "%d: %f, %f\n", i, p.x, p.y ); */ { float A; @@ -207,17 +202,21 @@ Panner::draw ( void ) fl_color( (Fl_Color) 10 + i ); - const int bx = tx + ((tw / 2) * p->x + (tw / 2)); - const int by = ty + ((th / 2) * p->y + (th / 2)); + float px, py; - fl_rectf( bx, by, pw(), ph() ); + p->axes( &px, &py ); + + const int bx = tx + ((tw / 2) * px + (tw / 2)); + const int by = ty + ((th / 2) * py + (th / 2)); + + fl_pie( bx, by, pw(), ph(), 0, 360 ); char pat[4]; snprintf( pat, 4, "%d", i + 1 ); fl_color( FL_BLACK ); fl_font( FL_HELVETICA, ph() + 2 ); - fl_draw( pat, bx, by + ph() ); + fl_draw( pat, bx + 1, by + 1, pw() - 1, ph() - 1, FL_ALIGN_CENTER ); } } @@ -246,10 +245,12 @@ Panner::handle ( int m ) float X = Fl::event_x() - x(); float Y = Fl::event_y() - y(); - drag->x = (float)(X / (w() / 2)) - 1.0f; - drag->y = (float)(Y / (h() / 2)) - 1.0f; + drag->angle( (float)(X / (w() / 2)) - 1.0f, (float)(Y / (h() / 2)) - 1.0f ); - printf( "%f\n", drag->distance( angle_to_axes( _configs[ _outs ][ 0 ] ) ) ); +/* drag->x = (float)(X / (w() / 2)) - 1.0f; */ +/* drag->y = (float)(Y / (h() / 2)) - 1.0f; */ + +/* printf( "%f\n", drag->distance( angle_to_axes( _configs[ _outs ][ 0 ] ) ) ); */ redraw(); diff --git a/Panner.H b/Panner.H index 919d20d..e88e44c 100644 --- a/Panner.H +++ b/Panner.H @@ -34,18 +34,67 @@ class Panner : public Fl_Widget struct Point { /* axes */ - float x, y; - Point ( ) : x( 0.0f ), y( 0.0f ) { } - Point ( float X, float Y ) : x( X ), y( Y ) { } + /* distance from center (from 0 to 1) */ + float d; + /* angle */ + float a; + Point ( ) : d( 0.0f ), a( 0.0f ) { } + Point ( float X, float Y ) : d( X ), a( Y ) { } - /* return the distance between the point and that referenced by /p/ */ + /** translate angle /a/ into x/y coords and place the result in /X/ and /Y/ */ + void + axes ( float *X, float *Y ) const + { + /* rotate */ + float A = ( 270 - a ) * ( M_PI / 180 ); + + *X = -d * cosf( A ); + *Y = d * sinf( A ); + } + + void + angle ( float X1, float Y1 ) + { + + float X2, Y2; + + Y2 = X2 = 0; + + float t; + + t = atan2( X2 - X1, Y2 - Y1 ); + + a = t * (180 / M_PI); + + if ( a < 0 ) + a = 360 + a; + + a = 360 - a; + + /* standard distance calculation */ + d = sqrt( pow( X2 - X1, 2 ) + pow( Y2 - Y1, 2 ) ); + + if ( d > 1.0f ) + d = 1.0f; + } + + /** return the distance between the point and that referenced by /p/ */ float distance ( const Point &p ) { - return sqrt( pow( x - p.x, 2 ) + pow( y - p.y, 2 ) ); + /* first, transform point coords */ + + float x1, y1, x2, y2; + + axes( &x1, &y1 ); + p.axes( &x2, &y2 ); + + /* standard distance calculation */ + return sqrt( pow( x1 - x2, 2 ) + pow( y1 - y2, 2 ) ); } + }; @@ -55,8 +104,8 @@ class Panner : public Fl_Widget vector _points; - static int pw ( void ) { return 6; } - static int ph ( void ) { return 6; } + static int pw ( void ) { return 12; } + static int ph ( void ) { return 12; } static int _configs[][12]; @@ -71,16 +120,28 @@ class Panner : public Fl_Widget Point * event_point ( void ); Point angle_to_axes ( float a ); + enum { + NONE = -1, + R = 90, + L = 270, + C = 0, + FL = 315, + FR = 45, + RL = 225, + RR = 135, + }; + public: + Panner ( int X, int Y, int W, int H, const char *L = 0 ) : Fl_Widget( X, Y, W, H, L ) { _ins = _outs = 4; - _points.push_back( Point( -1, -1 ) ); - _points.push_back( Point( 1, 1 ) ); - _points.push_back( Point( -1, 1 ) ); - _points.push_back( Point( 1, -1 ) ); + _points.push_back( Point( 1, FL ) ); + _points.push_back( Point( 1, FR ) ); + _points.push_back( Point( 1, RL ) ); + _points.push_back( Point( 1, RR ) ); _outs = 5; }