6 #include <qpopupmenu.h>
9 #include <Music/Music.h>
11 DialView::DialView(QWidget* parent)
12 : QFrame(parent, "DialView")
20 setting_showTolerance = new QAction(this);
21 setting_showTolerance->setMenuText(tr("Show tolerance"));
22 setting_showTolerance->setToggleAction(true);
23 setting_showTolerance->setOn(true);
24 connect(setting_showTolerance, SIGNAL(toggled(bool)), this, SLOT(update()));
25 setting_showTolerance->addTo(&m_popup_menu);
27 setting_showTrace = new QAction(this);
28 setting_showTrace->setMenuText(tr("Show trace"));
29 setting_showTrace->setToggleAction(true);
30 setting_showTrace->setOn(true);
31 connect(setting_showTrace, SIGNAL(toggled(bool)), this, SLOT(update()));
32 setting_showTrace->addTo(&m_popup_menu);
34 setting_useCents = new QAction(this);
35 setting_useCents->setMenuText(tr("Use cents"));
36 setting_useCents->setToggleAction(true);
37 setting_useCents->setOn(true);
38 connect(setting_useCents, SIGNAL(toggled(bool)), this, SLOT(update()));
39 setting_useCents->addTo(&m_popup_menu);
41 m_popup_menu.insertItem(new Title(tr("Scale range"), &m_popup_menu));
42 setting_spinScale = new QSpinBox(5, 100, 1, &m_popup_menu);
43 setting_spinScale->setValue(50);
44 QToolTip::add(setting_spinScale, tr("Scale range (in cents)"));
45 connect(setting_spinScale, SIGNAL(valueChanged(int)), this, SLOT(update()));
46 m_popup_menu.insertItem(setting_spinScale);
51 s_settings->writeEntry("showTolerance", setting_showTolerance->isOn());
52 s_settings->writeEntry("showTrace", setting_showTrace->isOn());
53 s_settings->writeEntry("useCents", setting_useCents->isOn());
54 s_settings->writeEntry("spinScale", setting_spinScale->value());
58 setting_showTolerance->setOn(s_settings->readBoolEntry("showTolerance", setting_showTolerance->isOn()));
59 setting_showTrace->setOn(s_settings->readBoolEntry("showTrace", setting_showTrace->isOn()));
60 setting_useCents->setOn(s_settings->readBoolEntry("useCents", setting_useCents->isOn()));
62 setting_spinScale->setValue(s_settings->readNumEntry("spinScale", setting_spinScale->value()));
64 void DialView::clearSettings()
66 s_settings->removeEntry("showTolerance");
67 s_settings->removeEntry("showTrace");
68 s_settings->removeEntry("useCents");
69 s_settings->removeEntry("spinScale");
72 void DialView::drawTextTickCent(QPainter& p, int bigw, int bigh, int r)
77 int bw = bigw/2-p.fontMetrics().height()+p.fontMetrics().height()/2+2;
78 int bh = bigh-p.fontMetrics().height()+p.fontMetrics().height()/2+2;
80 // only work within range that is a pure multiple of r
81 int range = int(setting_spinScale->value()/r)*r;
83 float scale = 50.0f/setting_spinScale->value()/100.0f;
84 for(int i=-range; i<=range; i+=r)
86 txt = QString::number(i);
87 float angle = (150.0f/180.0f)*i*scale*Math::Pi + Math::Pi/2;
88 QPoint pos(int(-bw*cos(angle)),int(-bh*sin(angle)));
90 p.translate(pos.x(), pos.y());
92 if(height()>width()) p.rotate(90);
93 p.drawText(-p.fontMetrics().width(txt)/2,p.fontMetrics().height()/2, txt);
94 if(height()>width()) p.rotate(-90);
96 p.translate(-pos.x(), -pos.y());
99 void DialView::drawTicksCent(QPainter& p, int bigw, int bigh, int r, int ticks_size, int h)
101 int sw = int(bigw/2.0f-p.fontMetrics().height()-ticks_size);
102 int sh = bigh-p.fontMetrics().height()-ticks_size;
106 // only work within range that is a pure multiple of r
107 float range = int(setting_spinScale->value()/r)*r;
109 float scale = 50.0f/setting_spinScale->value()/100.0f;
110 for(float i=-range; i<=range; i+=r)
112 float angle = (150.0f/180.0f)*i*scale*Math::Pi + Math::Pi/2;
113 p.drawLine(-QPoint(int(sw*cos(angle)),int(sh*sin(angle))), -QPoint(int(bw*cos(angle)),int(bh*sin(angle))));
116 void DialView::drawTextTickFrac(QPainter& p, int bigw, int bigh, int num, int den)
125 txt = QString::number(den*(50/setting_spinScale->value()));
128 int bw = bigw/2-p.fontMetrics().height()+p.fontMetrics().height()/2+2;
129 int bh = bigh-p.fontMetrics().height()+p.fontMetrics().height()/2+2;
130 float angle = deg/180.0f*Math::Pi + Math::Pi/2;
131 QPoint pos(int(-bw*cos(angle)),int(-bh*sin(angle)));
133 p.translate(pos.x(), pos.y());
135 if(height()>width()) p.rotate(90);
136 p.drawText(-p.fontMetrics().width(txt)/2,p.fontMetrics().height()/2, txt);
137 if(height()>width()) p.rotate(-90);
139 p.translate(-pos.x(), -pos.y());
141 void DialView::drawTicksFrac(QPainter& p, int bigw, int bigh, float r, int ticks_size, int h)
143 int sw = bigw/2-p.fontMetrics().height()-ticks_size;
144 int sh = bigh-p.fontMetrics().height()-ticks_size;
147 for(float i=-0.5f+r; i<0.5f; i+=2*r)
149 float angle = (150.0f/180.0f)*i*Math::Pi + Math::Pi/2;
150 p.drawLine(-QPoint(int(sw*cos(angle)),int(sh*sin(angle))), -QPoint(int(bw*cos(angle)),int(bh*sin(angle))));
154 void DialView::setError(float error)
160 void DialView::drawContents(QPainter* pp)
164 float human_tol = Music::f2hf(441.0,440.0); // TODO
166 if(setting_useCents->isOn())
167 scale = 50.0f/setting_spinScale->value();
169 scale = int(50/setting_spinScale->value());
174 QPoint c(width()/2,height());
175 QPoint unity_center = c+QPoint(p.fontMetrics().width("cent"),0);
177 if(setting_useCents->isOn()) unity = "cents";
181 c = QPoint(width(), height()/2);
184 unity_center = c+QPoint(-p.fontMetrics().width(unity),-p.fontMetrics().height());
186 int ticks_size = bigh/10;
189 p.setPen(QColor(0,0,0));
190 p.drawText(unity_center, unity);
192 p.translate(c.x(), c.y());
198 int pie_width = bigw/2-p.fontMetrics().height()-ticks_size-2;
199 int pie_height = bigh-p.fontMetrics().height()-ticks_size-2;
200 p.setBrush(QColor(123,205,145));
202 pen1.setColor(QColor(83,165,105));
203 // pen1.setStyle(Qt::DashLine);
206 if(setting_showTolerance->isOn())
208 float pie_deg = (150.0f/180.0f)*scale*human_tol*180;
209 p.drawPie(-pie_width,-pie_height,2*pie_width,2*pie_height, int((90-pie_deg)*16),int(2*pie_deg*16));
213 if((m_error>-1.0f && m_error<1.0f) && setting_showTrace->isOn() && m_max_error-m_min_error>0.0)
215 int line_width = ticks_size/4;
216 int mm_height = pie_height - line_width/2;
217 int mm_width = pie_width - line_width/2;
219 pen3.setColor(QColor(128,128,128));
220 pen3.setWidth(line_width);
223 float mm_degf = (150.0f/180.0f)*scale*180;
224 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));
228 p.setPen(QColor(0,0,0));
229 if(setting_useCents->isOn())
232 if(setting_spinScale->value() <= 25) grad=5;
233 if(setting_spinScale->value() <= 10) grad=1;
234 drawTextTickCent(p, bigw, bigh, grad);
238 drawTextTickFrac(p, bigw, bigh, 0,1);
239 drawTextTickFrac(p, bigw, bigh, 1,2);
240 drawTextTickFrac(p, bigw, bigh, -1,2);
241 drawTextTickFrac(p, bigw, bigh, 1,4);
242 drawTextTickFrac(p, bigw, bigh, -1,4);
243 drawTextTickFrac(p, bigw, bigh, 1,8);
244 drawTextTickFrac(p, bigw, bigh, -1,8);
245 drawTextTickFrac(p, bigw, bigh, 1,16);
246 drawTextTickFrac(p, bigw, bigh, -1,16);
250 int sw = bigw/2-p.fontMetrics().height()-ticks_size;
251 int sh = bigh-p.fontMetrics().height()-ticks_size;
252 int bw = sw + ticks_size;
253 int bh = sh + ticks_size;
254 if(setting_useCents->isOn())
256 drawTicksCent(p, bigw, bigh, 10, ticks_size, ticks_size);
257 drawTicksCent(p, bigw, bigh, 5, ticks_size, int(ticks_size * 0.6));
258 drawTicksCent(p, bigw, bigh, 1, ticks_size, int(ticks_size * 0.3));
262 for(float i=-1.0f; i<=1.0f; i+=0.25f)
264 float angle = (150.0f/360.0f)*i*Math::Pi + Math::Pi/2;
265 p.drawLine(-QPoint(int(sw*cos(angle)),int(sh*sin(angle))), -QPoint(int(bw*cos(angle)),int(bh*sin(angle))));
267 drawTicksFrac(p, bigw, bigh, 0.125f, ticks_size, 2*ticks_size/3);
268 drawTicksFrac(p, bigw, bigh, 0.0625f, ticks_size, ticks_size/2);
269 drawTicksFrac(p, bigw, bigh, 0.03125f, ticks_size, ticks_size/3);
273 if(m_error>-1.0f && m_error<1.0f)
275 float angle = (150.0f/180.0f)*scale*m_error*Math::Pi + Math::Pi/2;
276 QPoint final_point = -QPoint(int((pie_width-2)*cos(angle)),int((pie_height-2)*sin(angle)));
277 QPoint mid_point = 9*final_point/10;
280 pen2.setColor(QColor(64,64,64));
282 p.drawLine(QPoint(0,0), mid_point);
285 p.drawLine(mid_point, final_point);