9 #include <qwidgetaction.h>
10 #include <qboxlayout.h>
11 #include <Music/Music.h>
13 DialView::DialView(QWidget* parent)
15 , View(tr("Dial"), this)
22 setting_showTolerance = new QAction(tr("Show tolerance"), this);
23 setting_showTolerance->setCheckable(true);
24 setting_showTolerance->setChecked(true);
25 connect(setting_showTolerance, SIGNAL(toggled(bool)), this, SLOT(update()));
26 m_popup_menu.addAction(setting_showTolerance);
28 setting_showTrace = new QAction(tr("Show trace"), this);
29 setting_showTrace->setCheckable(true);
30 setting_showTrace->setChecked(true);
31 connect(setting_showTrace, SIGNAL(toggled(bool)), this, SLOT(update()));
32 m_popup_menu.addAction(setting_showTrace);
34 setting_useCents = new QAction(tr("Use cents"), this);
35 setting_useCents->setCheckable(true);
36 setting_useCents->setChecked(true);
37 connect(setting_useCents, SIGNAL(toggled(bool)), this, SLOT(update()));
38 m_popup_menu.addAction(setting_useCents);
40 QHBoxLayout* scaleActionLayout = new QHBoxLayout(&m_popup_menu);
42 QLabel* scaleActionTitle = new QLabel(tr("Scale range"), &m_popup_menu);
43 scaleActionLayout->addWidget(scaleActionTitle);
45 setting_spinScale = new QSpinBox(&m_popup_menu);
46 setting_spinScale->setMinimum(5);
47 setting_spinScale->setMaximum(100);
48 setting_spinScale->setSingleStep(1);
49 setting_spinScale->setValue(50);
50 setting_spinScale->setToolTip(tr("Scale range (in cents)"));
51 connect(setting_spinScale, SIGNAL(valueChanged(int)), this, SLOT(update()));
52 scaleActionLayout->addWidget(setting_spinScale);
54 QWidget* scaleActionWidget = new QWidget(&m_popup_menu);
55 scaleActionWidget->setLayout(scaleActionLayout);
57 QWidgetAction* scaleAction = new QWidgetAction(&m_popup_menu);
58 scaleAction->setDefaultWidget(scaleActionWidget);
59 m_popup_menu.addAction(scaleAction);
64 s_settings->setValue("showTolerance", setting_showTolerance->isChecked());
65 s_settings->setValue("showTrace", setting_showTrace->isChecked());
66 s_settings->setValue("useCents", setting_useCents->isChecked());
67 s_settings->setValue("spinScale", setting_spinScale->value());
71 setting_showTolerance->setChecked(s_settings->value("showTolerance", setting_showTolerance->isChecked()).toBool());
72 setting_showTrace->setChecked(s_settings->value("showTrace", setting_showTrace->isChecked()).toBool());
73 setting_useCents->setChecked(s_settings->value("useCents", setting_useCents->isChecked()).toBool());
74 setting_spinScale->setValue(s_settings->value("spinScale", setting_spinScale->value()).toInt());
76 void DialView::clearSettings()
78 s_settings->remove("showTolerance");
79 s_settings->remove("showTrace");
80 s_settings->remove("useCents");
81 s_settings->remove("spinScale");
84 void DialView::drawTextTickCent(QPainter& p, int bigw, int bigh, int r)
89 int bw = bigw/2-p.fontMetrics().height()+p.fontMetrics().height()/2+2;
90 int bh = bigh-p.fontMetrics().height()+p.fontMetrics().height()/2+2;
92 // only work within range that is a pure multiple of r
93 int range = int(setting_spinScale->value()/r)*r;
95 float scale = 50.0f/setting_spinScale->value()/100.0f;
96 for(int i=-range; i<=range; i+=r)
98 txt = QString::number(i);
99 float angle = (150.0f/180.0f)*i*scale*Math::Pi + Math::Pi/2;
100 QPoint pos(int(-bw*cos(angle)),int(-bh*sin(angle)));
102 p.translate(pos.x(), pos.y());
104 if(height()>width()) p.rotate(90);
105 p.drawText(-p.fontMetrics().width(txt)/2,p.fontMetrics().height()/2, txt);
106 if(height()>width()) p.rotate(-90);
108 p.translate(-pos.x(), -pos.y());
111 void DialView::drawTicksCent(QPainter& p, int bigw, int bigh, int r, int ticks_size, int h)
113 int sw = int(bigw/2.0f-p.fontMetrics().height()-ticks_size);
114 int sh = bigh-p.fontMetrics().height()-ticks_size;
118 // only work within range that is a pure multiple of r
119 float range = int(setting_spinScale->value()/r)*r;
121 float scale = 50.0f/setting_spinScale->value()/100.0f;
122 for(float i=-range; i<=range; i+=r)
124 float angle = (150.0f/180.0f)*i*scale*Math::Pi + Math::Pi/2;
125 p.drawLine(-QPoint(int(sw*cos(angle)),int(sh*sin(angle))), -QPoint(int(bw*cos(angle)),int(bh*sin(angle))));
128 void DialView::drawTextTickFrac(QPainter& p, int bigw, int bigh, int num, int den)
137 txt = QString::number(den*(50/setting_spinScale->value()));
140 int bw = bigw/2-p.fontMetrics().height()+p.fontMetrics().height()/2+2;
141 int bh = bigh-p.fontMetrics().height()+p.fontMetrics().height()/2+2;
142 float angle = deg/180.0f*Math::Pi + Math::Pi/2;
143 QPoint pos(int(-bw*cos(angle)),int(-bh*sin(angle)));
145 p.translate(pos.x(), pos.y());
147 if(height()>width()) p.rotate(90);
148 p.drawText(-p.fontMetrics().width(txt)/2,p.fontMetrics().height()/2, txt);
149 if(height()>width()) p.rotate(-90);
151 p.translate(-pos.x(), -pos.y());
153 void DialView::drawTicksFrac(QPainter& p, int bigw, int bigh, float r, int ticks_size, int h)
155 int sw = bigw/2-p.fontMetrics().height()-ticks_size;
156 int sh = bigh-p.fontMetrics().height()-ticks_size;
159 for(float i=-0.5f+r; i<0.5f; i+=2*r)
161 float angle = (150.0f/180.0f)*i*Math::Pi + Math::Pi/2;
162 p.drawLine(-QPoint(int(sw*cos(angle)),int(sh*sin(angle))), -QPoint(int(bw*cos(angle)),int(bh*sin(angle))));
166 void DialView::setError(float error)
172 void DialView::paintEvent(QPaintEvent* event)
176 float human_tol = Music::f2hf(441.0,440.0); // TODO
178 if(setting_useCents->isChecked())
179 scale = 50.0f/setting_spinScale->value();
181 scale = int(50/setting_spinScale->value());
186 QPoint c(width()/2,height());
187 QPoint unity_center = c+QPoint(p.fontMetrics().width("cent"),0);
189 if(setting_useCents->isChecked()) unity = "cents";
193 c = QPoint(width(), height()/2);
196 unity_center = c+QPoint(-p.fontMetrics().width(unity),-p.fontMetrics().height());
198 int ticks_size = bigh/10;
201 p.setPen(QColor(0,0,0));
202 p.drawText(unity_center, unity);
204 p.translate(c.x(), c.y());
210 int pie_width = bigw/2-p.fontMetrics().height()-ticks_size-2;
211 int pie_height = bigh-p.fontMetrics().height()-ticks_size-2;
212 p.setBrush(QColor(123,205,145));
214 pen1.setColor(QColor(83,165,105));
215 // pen1.setStyle(Qt::DashLine);
218 if(setting_showTolerance->isChecked())
220 float pie_deg = (150.0f/180.0f)*scale*human_tol*180;
221 p.drawPie(-pie_width,-pie_height,2*pie_width,2*pie_height, int((90-pie_deg)*16),int(2*pie_deg*16));
225 if((m_error>-1.0f && m_error<1.0f) && setting_showTrace->isChecked() && m_max_error-m_min_error>0.0)
227 int line_width = ticks_size/4;
228 int mm_height = pie_height - line_width/2;
229 int mm_width = pie_width - line_width/2;
231 pen3.setColor(QColor(128,128,128));
232 pen3.setWidth(line_width);
235 float mm_degf = (150.0f/180.0f)*scale*180;
236 p.drawArc(-mm_width,-mm_height,2*mm_width,2*mm_height,int((90-mm_degf*m_min_error)*16),int((-mm_degf*(m_max_error-m_min_error))*16));
240 p.setPen(QColor(0,0,0));
241 if(setting_useCents->isChecked())
244 if(setting_spinScale->value() <= 25) grad=5;
245 if(setting_spinScale->value() <= 10) grad=1;
246 drawTextTickCent(p, bigw, bigh, grad);
250 drawTextTickFrac(p, bigw, bigh, 0,1);
251 drawTextTickFrac(p, bigw, bigh, 1,2);
252 drawTextTickFrac(p, bigw, bigh, -1,2);
253 drawTextTickFrac(p, bigw, bigh, 1,4);
254 drawTextTickFrac(p, bigw, bigh, -1,4);
255 drawTextTickFrac(p, bigw, bigh, 1,8);
256 drawTextTickFrac(p, bigw, bigh, -1,8);
257 drawTextTickFrac(p, bigw, bigh, 1,16);
258 drawTextTickFrac(p, bigw, bigh, -1,16);
262 int sw = bigw/2-p.fontMetrics().height()-ticks_size;
263 int sh = bigh-p.fontMetrics().height()-ticks_size;
264 int bw = sw + ticks_size;
265 int bh = sh + ticks_size;
266 if(setting_useCents->isChecked())
268 drawTicksCent(p, bigw, bigh, 10, ticks_size, ticks_size);
269 drawTicksCent(p, bigw, bigh, 5, ticks_size, int(ticks_size * 0.6));
270 drawTicksCent(p, bigw, bigh, 1, ticks_size, int(ticks_size * 0.3));
274 for(float i=-1.0f; i<=1.0f; i+=0.25f)
276 float angle = (150.0f/360.0f)*i*Math::Pi + Math::Pi/2;
277 p.drawLine(-QPoint(int(sw*cos(angle)),int(sh*sin(angle))), -QPoint(int(bw*cos(angle)),int(bh*sin(angle))));
279 drawTicksFrac(p, bigw, bigh, 0.125f, ticks_size, 2*ticks_size/3);
280 drawTicksFrac(p, bigw, bigh, 0.0625f, ticks_size, ticks_size/2);
281 drawTicksFrac(p, bigw, bigh, 0.03125f, ticks_size, ticks_size/3);
285 if(m_error>-1.0f && m_error<1.0f)
287 float angle = (150.0f/180.0f)*scale*m_error*Math::Pi + Math::Pi/2;
288 QPoint final_point = -QPoint(int((pie_width-2)*cos(angle)),int((pie_height-2)*sin(angle)));
289 QPoint mid_point = 9*final_point/10;
292 pen2.setColor(QColor(64,64,64));
294 p.drawLine(QPoint(0,0), mid_point);
297 p.drawLine(mid_point, final_point);