/*******************************************************************************/ /* Copyright (C) 2008 Jonathan Moore Liles */ /* */ /* This program is free software; you can redistribute it and/or modify it */ /* under the terms of the GNU General Public License as published by the */ /* Free Software Foundation; either version 2 of the License, or (at your */ /* option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, but WITHOUT */ /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */ /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for */ /* more details. */ /* */ /* You should have received a copy of the GNU General Public License along */ /* with This program; see the file COPYING. If not,write to the Free Software */ /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /*******************************************************************************/ #pragma once #include #include #include #include #include using namespace std; class Panner : public Fl_Widget { void draw_the_box( int, int, int, int ); struct Point { /* axes */ /* distance from center (from 0 to 1) */ float d; /* angle */ float a; Point ( ) : d( 0.0f ), a( 0.0f ) { } Point ( float D, float A ) : d( D ), a( A ) { } /** 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 ); } float azimuth ( void ) const { return a > 180.0f ? a - 360.0f : a; } float elevation ( void ) const { return ( 1.0f - d ) * 90.0f; } void azimuth ( float v ) { a = v < 0.0f ? v + 360.0f : v; a = a < 0.0f ? 0.0f : a > 360.0f ? 360.0f : a; } void elevation ( float v ) { d = 1.0f - ( v / 90.0f ); d = d < 0.0f ? 0.0f : d > 1.0f ? 1.0f : d; } /** set point position in X, Y coordinates (0.0 to 1.0) */ 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 ) { /* 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 ) ); } }; /* channel configuration */ int _ins, _outs; bool _bypassed; vector _points; static int pw ( void ) { return 12; } static int ph ( void ) { return 12; } static int _configs[][12]; void bbox ( int &X, int &Y, int &W, int &H ) const { W = w() - Fl::box_dw( box() ); H = h() - Fl::box_dh( box() ); X = x() + Fl::box_dx( box() ); Y = y() + Fl::box_dy( box() ); } void point_bbox ( const Point *p, int *X, int *Y, int *W, int *H ) const; 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, }; static Point * drag; protected: virtual void draw ( void ); virtual int handle ( int ); public: Panner ( int X, int Y, int W, int H, const char *L = 0 ) : Fl_Widget( X, Y, W, H, L ) { _bypassed = false; _ins = 1; _outs = 1; // _ins = _outs = 4; // _points.push_back( Point( 1, FL ) ); _points.push_back( Point( 1, C ) ); /* _points.push_back( Point( 1, FR ) ); */ /* _points.push_back( Point( 1, RL ) ); */ /* _points.push_back( Point( 1, RR ) ); */ } virtual ~Panner ( ) { } Panner::Point *point ( int i ); };