diff options
Diffstat (limited to 'src/ui/balanceknob.cpp')
| -rw-r--r-- | src/ui/balanceknob.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/ui/balanceknob.cpp b/src/ui/balanceknob.cpp new file mode 100644 index 0000000..1c2faa4 --- /dev/null +++ b/src/ui/balanceknob.cpp @@ -0,0 +1,124 @@ +#include "balanceknob.h" + +#include <tqpainter.h> +#include <tqpixmap.h> +#include <tqimage.h> +#include <tqevent.h> +#include <math.h> + +static const double DEG2RAD = M_PI / 180.0; +static const double TRAVEL = 135.0; // degrees each side from centre + +BalanceKnob::BalanceKnob( int minVal, int maxVal, int val, TQWidget *parent ) + : TQWidget(parent), + m_min(minVal), m_max(maxVal), m_value(val), + m_dragY(0), m_dragValue(0), m_dragging(false) +{ + setFixedSize( 30, 30 ); + setBackgroundMode( TQt::NoBackground ); +} + +void BalanceKnob::setValue( int v ) +{ + v = v < m_min ? m_min : v > m_max ? m_max : v; + if ( v == m_value ) return; + m_value = v; + update(); + emit valueChanged( v ); +} + +void BalanceKnob::paintEvent( TQPaintEvent * ) +{ + // 2× supersampling for smooth edges (TQt3 has no native AA) + const int S = 2; + int W = width() * S, H = height() * S; + int cx = W / 2, cy = H / 2; + int r = ( W < H ? W : H ) / 2 - S; + + TQPixmap pm( W, H ); + pm.fill( paletteBackgroundColor() ); + TQPainter p( &pm ); + + double mid = ( m_min + m_max ) / 2.0; + double half = ( m_max - m_min ) / 2.0; + + // ---- range track arc (270° from 7:30 clockwise to 4:30) ----------------- + p.setPen( TQPen( TQColor(90, 90, 90), S * 2 ) ); + p.setBrush( TQt::NoBrush ); + p.drawArc( cx - r, cy - r, 2*r, 2*r, 225*16, -270*16 ); + + // ---- value arc (from 12-o'clock to current position) -------------------- + double current_qt = 90.0 - ( (m_value - mid) / half ) * TRAVEL; + int spanAngle = (int)( (current_qt - 90.0) * 16.0 ); + if ( spanAngle != 0 ) { + p.setPen( TQPen( TQColor(90, 140, 220), S * 2 ) ); + p.drawArc( cx - r, cy - r, 2*r, 2*r, 90*16, spanAngle ); + } + + // ---- knob body ----------------------------------------------------------- + int kr = r - S * 3; + p.setPen( TQt::NoPen ); + + p.setBrush( TQColor(38, 38, 42) ); + p.drawEllipse( cx - kr, cy - kr, 2*kr, 2*kr ); + + p.setBrush( TQColor(68, 68, 74) ); + p.drawEllipse( cx - kr + S, cy - kr + S, 2*kr - S*3, 2*kr - S*3 ); + + // ---- centre rest dot ---------------------------------------------------- + p.setPen( TQt::NoPen ); + p.setBrush( TQColor(100, 100, 110) ); + p.drawEllipse( cx - S, cy - kr + S*2, S*2, S*2 ); + + // ---- indicator line ----------------------------------------------------- + double angle_rad = ( (m_value - mid) / half ) * TRAVEL * DEG2RAD; + int ix = cx + (int)( (kr - S*3) * sin( angle_rad ) ); + int iy = cy - (int)( (kr - S*3) * cos( angle_rad ) ); + + p.setPen( TQPen( TQt::white, S * 2 ) ); + p.drawLine( cx, cy, ix, iy ); + + p.end(); + + // Scale back down and blit + TQImage scaled = pm.convertToImage().smoothScale( width(), height() ); + TQPainter out( this ); + out.drawImage( 0, 0, scaled ); +} + +void BalanceKnob::mousePressEvent( TQMouseEvent *e ) +{ + if ( e->button() == TQt::LeftButton ) { + m_dragY = e->globalPos().y(); + m_dragValue = m_value; + m_dragging = true; + grabMouse(); + } +} + +void BalanceKnob::mouseMoveEvent( TQMouseEvent *e ) +{ + if ( !m_dragging ) return; + int delta = m_dragY - e->globalPos().y(); // drag up = increase + setValue( m_dragValue + delta ); +} + +void BalanceKnob::mouseReleaseEvent( TQMouseEvent * ) +{ + if ( m_dragging ) { + m_dragging = false; + releaseMouse(); + } +} + +void BalanceKnob::mouseDoubleClickEvent( TQMouseEvent * ) +{ + setValue( (int)( (m_min + m_max) / 2.0 ) ); +} + +void BalanceKnob::wheelEvent( TQWheelEvent *e ) +{ + setValue( m_value + ( e->delta() > 0 ? 5 : -5 ) ); +} + +#include "balanceknob.moc" |
