@@ -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 ) ); | |||||
max_color( FL_RED ); | |||||
/* initialize gradients */ | |||||
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 bw = w() / _divisions; | |||||
int bh = h() / _segments; | |||||
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 ); | |||||
Fl_Color c = fl_color_average( _max_color, _min_color, (float) p / _divisions ); | |||||
if ( old_value() > value() ) | |||||
{ | |||||
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 = fl_color_average( FL_BLACK, c, _dim ); | |||||
c = dim_div_color( p ); | |||||
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 ); */ | |||||
} | |||||
} | } |
@@ -26,17 +26,31 @@ | |||||
class DPM : public Meter | class DPM : public Meter | ||||
{ | { | ||||
int _divisions; | |||||
float _dim; | |||||
int _segments; | |||||
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; } | |||||
void divisions ( int v ) { _divisions = v; } | |||||
bool segments ( void ) const { return _segments; } | |||||
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; } | |||||
void min_color ( Fl_Color v ) { _min_color = v; } | |||||
Fl_Color max_color ( void ) const { return _max_color; } | |||||
void max_color ( Fl_Color v ) { _max_color = v; } | |||||
static | |||||
void | |||||
blend ( Fl_Color min, Fl_Color max ) | |||||
{ | |||||
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 ); | |||||
} | |||||
}; | }; |
@@ -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 ); | |||||
_old_value = _value; | |||||
_value = v; | |||||
if ( _value > _peak ) | |||||
_peak = _value; | |||||
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(); } | |||||
}; |