#include "balanceknob.h" #include #include #include #include #include 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"