Play with meters.

This commit is contained in:
Jonathan Moore Liles 2008-03-12 23:47:06 -05:00
parent 989d6b4d51
commit bd64101c75
3 changed files with 133 additions and 33 deletions

68
DPM.C
View File

@ -24,6 +24,11 @@
#include "DPM.H" #include "DPM.H"
/* we cache the gradient for (probably excessive) speed */
float DPM::_dim;
Fl_Color DPM::_gradient[128] = { (Fl_Color)-1 };
Fl_Color DPM::_dim_gradient[128];
#include <FL/Fl.H> #include <FL/Fl.H>
#include <FL/fl_draw.H> #include <FL/fl_draw.H>
#include <FL/Fl_Group.H> #include <FL/Fl_Group.H>
@ -34,13 +39,14 @@
DPM::DPM ( int X, int Y, int W, int H, const char *L ) : DPM::DPM ( int X, int Y, int W, int H, const char *L ) :
Meter( X, Y, W, H, L ) Meter( X, Y, W, H, L )
{ {
divisions( 64 ); segments( 64 );
type( FL_VERTICAL ); type( FL_VERTICAL );
dim( 0.80f ); dim( 0.70f );
min_color( fl_darker( FL_GREEN ) ); /* initialize gradients */
max_color( FL_RED ); if ( DPM::_gradient[ 0 ] == -1 )
DPM::blend( FL_GREEN, FL_RED );
box( FL_ROUNDED_BOX ); box( FL_ROUNDED_BOX );
} }
@ -72,32 +78,60 @@ DPM::draw_label ( void )
void void
DPM::draw ( void ) DPM::draw ( void )
{ {
// draw_box( FL_FLAT_BOX, x(), y(), w(), h(), color() );
int v = pos( value() ); int v = pos( value() );
int pv = pos( peak() ); int pv = pos( peak() );
int bh = h() / _divisions; int bh = h() / _segments;
int bw = w() / _divisions; int bw = w() / _segments;
if ( damage() & FL_DAMAGE_ALL ) if ( damage() == FL_DAMAGE_ALL )
draw_label(); draw_label();
for ( int p = _divisions; p > 0; p-- ) const int active = active_r();
int hi, lo;
/* only draw as many segments as necessary */
if ( damage() == FL_DAMAGE_USER1 )
{ {
// Fl_Color c = fl_color_average( _min_color, _max_color, ((30.0f * log10f( (float)(_divisions - p ) ) )) / _divisions ); if ( old_value() > value() )
Fl_Color c = fl_color_average( _max_color, _min_color, (float) p / _divisions ); {
hi = pos( old_value() );
lo = v;
}
else
{
hi = v;
lo = pos( old_value() );
}
}
else
{
lo = 0;
hi = _segments;
}
for ( int p = hi; p > lo; p-- )
{
Fl_Color c = DPM::div_color( p );
if ( p > v && p != pv ) if ( p > v && p != pv )
// c = fl_color_average( color(), c, _dim ); c = dim_div_color( p );
c = fl_color_average( FL_BLACK, c, _dim );
if ( ! active_r() ) if ( ! active )
c = fl_inactive( c ); c = fl_inactive( c );
if ( type() == FL_HORIZONTAL ) if ( type() == FL_HORIZONTAL )
draw_box( box(), x() + (p * bw), y(), bw, h(), c ); fl_draw_box( box(), x() + (p * bw), y(), bw, h(), c );
else else
draw_box( box(), x(), y() + h() - (p * bh), w(), bh, c ); fl_draw_box( box(), x(), y() + h() - (p * bh), w(), bh, c );
}
/* fl_color( c ); */
/* fl_rectf( x(), y() + h() - (p * bh), w(), bh ); */
/* fl_color( FL_BLACK ); */
/* fl_rect( x(), y() + h() - (p * bh), w(), bh ); */
}
} }

42
DPM.H
View File

@ -26,17 +26,31 @@
class DPM : public Meter class DPM : public Meter
{ {
int _divisions; int _segments;
float _dim;
Fl_Color _min_color;
Fl_Color _max_color;
int pos ( float v ) int pos ( float v )
{ {
return deflection( v ) * _divisions; return deflection( v ) * _segments;
} }
static float _dim;
static Fl_Color _gradient[];
static Fl_Color _dim_gradient[];
Fl_Color
div_color ( int i )
{
return _gradient[ i * 127 / _segments ];
}
Fl_Color
dim_div_color ( int i )
{
return _dim_gradient[ i * 127 / _segments ];
}
protected: protected:
virtual void draw_label ( void ); virtual void draw_label ( void );
@ -48,16 +62,20 @@ public:
// void value ( float v ) { if ( pos( v ) != pos( value() ) ) redraw(); Meter::value( v ) } // void value ( float v ) { if ( pos( v ) != pos( value() ) ) redraw(); Meter::value( v ) }
bool divisions ( void ) const { return _divisions; } bool segments ( void ) const { return _segments; }
void divisions ( int v ) { _divisions = v; } void segments ( int v ) { _segments = v; }
float dim ( void ) const { return _dim; } float dim ( void ) const { return _dim; }
void dim ( float v ) { _dim = v; redraw(); } void dim ( float v ) { _dim = v; redraw(); }
Fl_Color min_color ( void ) const { return _min_color; } static
void min_color ( Fl_Color v ) { _min_color = v; } void
blend ( Fl_Color min, Fl_Color max )
Fl_Color max_color ( void ) const { return _max_color; } {
void max_color ( Fl_Color v ) { _max_color = v; } for ( int i = 128; i-- ; )
_gradient[ i ] = fl_color_average( max, min, i / (float)128 );
for ( int i = 128; i-- ; )
_dim_gradient[ i ] = fl_color_average( FL_BLACK, _gradient[ i ], _dim );
}
}; };

56
Meter.H
View File

@ -19,10 +19,14 @@
/* Base class for all meters */ /* Base class for all meters */
#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
class Meter : public Fl_Widget class Meter : public Fl_Widget
{ {
float _peak; float _peak;
float _old_value;
float _value; float _value;
protected: protected:
@ -31,7 +35,12 @@ protected:
virtual int handle ( int m ) virtual int handle ( int m )
{ {
if ( m == FL_PUSH ) if ( m == FL_PUSH )
reset(); {
// if ( Fl::event_button3() )
// hide();
// else
reset();
}
return 0; return 0;
} }
@ -61,22 +70,31 @@ protected:
return def / 115.0f; return def / 115.0f;
} }
float old_value ( void ) const { return _old_value; }
public: public:
Meter ( int X, int Y, int W, int H, const char *L = 0 ) : Meter ( int X, int Y, int W, int H, const char *L = 0 ) :
Fl_Widget( X, Y, W, H, L ) Fl_Widget( X, Y, W, H, L )
{ {
_peak = _value = -80.0f; _peak = _value = -80.0f;
_old_value = 4.0f;
} }
virtual ~Meter ( ) { } virtual ~Meter ( ) { }
void value ( float v ) void value ( float v )
{ {
_value = v; if ( _value != v )
{
damage( FL_DAMAGE_USER1 );
if ( _value > _peak ) _old_value = _value;
_peak = _value; _value = v;
if ( _value > _peak )
_peak = _value;
}
} }
float value ( void ) const { return _value; } float value ( void ) const { return _value; }
@ -85,3 +103,33 @@ public:
void reset ( void ) { _peak = -80.0f; redraw(); } void reset ( void ) { _peak = -80.0f; redraw(); }
}; };
#include <FL/Fl_Group.H>
#include <stdio.h>
/* ... Extension methods for any group containing only meters. Access
* via a cast to (Meter_Pack *) */
class Meter_Pack : public Fl_Group
{
public:
/** return a pointer to the meter for channel /c/ in group of meters /g/ */
Meter *
channel ( int c )
{
if ( c > children() )
{
fprintf( stderr, "no such channel\n" );
return NULL;
}
return (Meter *)child( c );
}
int
channels ( void ) const { return children(); }
};