1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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"
|