comparison widgets/Thumbwheel.cpp @ 165:793df5f0c6cb

* Make the thumbwheel widget much smoother to use, and fix a bug in positioning
author Chris Cannam
date Thu, 12 Oct 2006 15:47:38 +0000
parents 9e6b3e239b9d
children 42118892f428
comparison
equal deleted inserted replaced
164:11949d0b2739 165:793df5f0c6cb
28 QWidget(parent), 28 QWidget(parent),
29 m_min(0), 29 m_min(0),
30 m_max(100), 30 m_max(100),
31 m_default(50), 31 m_default(50),
32 m_value(50), 32 m_value(50),
33 m_rotation(0.5),
33 m_orientation(orientation), 34 m_orientation(orientation),
34 m_speed(0.25), 35 m_speed(1.0),
35 m_tracking(true), 36 m_tracking(true),
36 m_showScale(true), 37 m_showScale(true),
37 m_clicked(false), 38 m_clicked(false),
38 m_atDefault(true), 39 m_atDefault(true),
39 m_clickValue(m_value) 40 m_clickRotation(m_rotation)
40 { 41 {
41 } 42 }
42 43
43 Thumbwheel::~Thumbwheel() 44 Thumbwheel::~Thumbwheel()
44 { 45 {
51 52
52 m_min = min; 53 m_min = min;
53 if (m_max <= m_min) m_max = m_min + 1; 54 if (m_max <= m_min) m_max = m_min + 1;
54 if (m_value < m_min) m_value = m_min; 55 if (m_value < m_min) m_value = m_min;
55 if (m_value > m_max) m_value = m_max; 56 if (m_value > m_max) m_value = m_max;
57
58 m_rotation = float(m_value - m_min) / float(m_max - m_min);
59 update();
56 } 60 }
57 61
58 int 62 int
59 Thumbwheel::getMinimumValue() const 63 Thumbwheel::getMinimumValue() const
60 { 64 {
68 72
69 m_max = max; 73 m_max = max;
70 if (m_min >= m_max) m_min = m_max - 1; 74 if (m_min >= m_max) m_min = m_max - 1;
71 if (m_value < m_min) m_value = m_min; 75 if (m_value < m_min) m_value = m_min;
72 if (m_value > m_max) m_value = m_max; 76 if (m_value > m_max) m_value = m_max;
77
78 m_rotation = float(m_value - m_min) / float(m_max - m_min);
79 update();
73 } 80 }
74 81
75 int 82 int
76 Thumbwheel::getMaximumValue() const 83 Thumbwheel::getMaximumValue() const
77 { 84 {
84 if (m_default == deft) return; 91 if (m_default == deft) return;
85 92
86 m_default = deft; 93 m_default = deft;
87 if (m_atDefault) { 94 if (m_atDefault) {
88 setValue(m_default); 95 setValue(m_default);
96 m_atDefault = true; // setValue unsets this
89 emit valueChanged(getValue()); 97 emit valueChanged(getValue());
90 } 98 }
91 } 99 }
92 100
93 int 101 int
97 } 105 }
98 106
99 void 107 void
100 Thumbwheel::setValue(int value) 108 Thumbwheel::setValue(int value)
101 { 109 {
102 if (m_value == value) return; 110 // std::cerr << "Thumbwheel::setValue(" << value << ") (from " << m_value
103 m_atDefault = false; 111 // << ", rotation " << m_rotation << ")" << std::endl;
104 112
105 if (value < m_min) value = m_min; 113 if (m_value != value) {
106 if (value > m_max) value = m_max; 114
107 m_value = value; 115 m_atDefault = false;
116
117 if (value < m_min) value = m_min;
118 if (value > m_max) value = m_max;
119 m_value = value;
120 }
121
122 m_rotation = float(m_value - m_min) / float(m_max - m_min);
108 update(); 123 update();
109 } 124 }
110 125
111 void 126 void
112 Thumbwheel::resetToDefault() 127 Thumbwheel::resetToDefault()
163 Thumbwheel::mousePressEvent(QMouseEvent *e) 178 Thumbwheel::mousePressEvent(QMouseEvent *e)
164 { 179 {
165 if (e->button() == Qt::LeftButton) { 180 if (e->button() == Qt::LeftButton) {
166 m_clicked = true; 181 m_clicked = true;
167 m_clickPos = e->pos(); 182 m_clickPos = e->pos();
168 m_clickValue = m_value; 183 m_clickRotation = m_rotation;
169 } else if (e->button() == Qt::MidButton) { 184 } else if (e->button() == Qt::MidButton) {
170 resetToDefault(); 185 resetToDefault();
171 } 186 }
172 } 187 }
173 188
185 if (m_orientation == Qt::Horizontal) { 200 if (m_orientation == Qt::Horizontal) {
186 dist = e->x() - m_clickPos.x(); 201 dist = e->x() - m_clickPos.x();
187 } else { 202 } else {
188 dist = e->y() - m_clickPos.y(); 203 dist = e->y() - m_clickPos.y();
189 } 204 }
190 int value = m_clickValue + lrintf(m_speed * dist); 205
191 if (value < m_min) value = m_min; 206 float rotation = m_clickRotation + (m_speed * dist) / 100;
192 if (value > m_max) value = m_max; 207 if (rotation < 0.f) rotation = 0.f;
208 if (rotation > 1.f) rotation = 1.f;
209 int value = lrintf(m_min + (m_max - m_min) * m_rotation);
193 if (value != m_value) { 210 if (value != m_value) {
194 setValue(value); 211 setValue(value);
195 if (m_tracking) emit valueChanged(getValue()); 212 if (m_tracking) emit valueChanged(getValue());
196 } 213 m_rotation = rotation;
214 } else if (fabsf(rotation - m_rotation) > 0.001) {
215 m_rotation = rotation;
216 repaint();
217 }
197 } 218 }
198 219
199 void 220 void
200 Thumbwheel::mouseReleaseEvent(QMouseEvent *e) 221 Thumbwheel::mouseReleaseEvent(QMouseEvent *e)
201 { 222 {
238 paint.drawRect(i, i, width() - i*2 - 1, height() - i*2 - 1); 259 paint.drawRect(i, i, width() - i*2 - 1, height() - i*2 - 1);
239 } 260 }
240 261
241 paint.setClipRect(QRect(bw, bw, width() - bw*2, height() - bw*2)); 262 paint.setClipRect(QRect(bw, bw, width() - bw*2, height() - bw*2));
242 263
243 float distance = float(m_value - m_min) / float(m_max - m_min); 264 float radians = m_rotation * 1.5f * M_PI;
244 float rotation = distance * 1.5f * M_PI;
245 265
246 // std::cerr << "value = " << m_value << ", min = " << m_min << ", max = " << m_max << ", rotation = " << rotation << std::endl; 266 // std::cerr << "value = " << m_value << ", min = " << m_min << ", max = " << m_max << ", rotation = " << rotation << std::endl;
247 267
248 int w = (m_orientation == Qt::Horizontal ? width() : height()) - bw*2; 268 int w = (m_orientation == Qt::Horizontal ? width() : height()) - bw*2;
249 269
255 275
256 paint.setRenderHint(QPainter::Antialiasing, true); 276 paint.setRenderHint(QPainter::Antialiasing, true);
257 277
258 for (int i = 0; i < notches; ++i) { 278 for (int i = 0; i < notches; ++i) {
259 279
260 float a0 = (2.f * M_PI * i) / notches + rotation; 280 float a0 = (2.f * M_PI * i) / notches + radians;
261 float a1 = a0 + M_PI / (notches * 2); 281 float a1 = a0 + M_PI / (notches * 2);
262 float a2 = (2.f * M_PI * (i + 1)) / notches + rotation; 282 float a2 = (2.f * M_PI * (i + 1)) / notches + radians;
263 283
264 float depth = cosf((a0 + a2) / 2); 284 float depth = cosf((a0 + a2) / 2);
265 if (depth < 0) continue; 285 if (depth < 0) continue;
266 286
267 float x0 = radius * sinf(a0) + w/2; 287 float x0 = radius * sinf(a0) + w/2;