comparison layer/TimeValueLayer.cpp @ 25:dcdb21b62dbb

* Refactor sparse models. Previously the 1D and time-value models duplicated a lot of code; now there is a base class (SparseModel) templated on the stored point type, and the subclasses define point types with the necessary characteristics. * Add NoteModel, a new SparseModel subclass. * Reorganise local feature description display. Instead of asking the layer to draw its own, just query it for a textual description and draw that in Pane. Greatly simplifies this part of the layer code. * Add local feature descriptions to colour 3D plot and waveform layers. * Add pitch in MIDI-pitch-and-cents to spectrogram layer. * Give AudioGenerator its own mutex to shorten lock times in CallbackPlaySource. * Minor adjustments to layers menu &c
author Chris Cannam
date Thu, 02 Feb 2006 16:10:19 +0000
parents ca57f70b0e48
children 94381052a6c9
comparison
equal deleted inserted replaced
24:6b794a2af3d9 25:dcdb21b62dbb
176 176
177 QPoint discard; 177 QPoint discard;
178 return !m_view->shouldIlluminateLocalFeatures(this, discard); 178 return !m_view->shouldIlluminateLocalFeatures(this, discard);
179 } 179 }
180 180
181 QRect
182 TimeValueLayer::getFeatureDescriptionRect(QPainter &paint, QPoint pos) const
183 {
184 return QRect(0, 0,
185 std::max(100, paint.fontMetrics().width(tr("No local points"))),
186 70); //!!!
187 }
188
189 //!!! too much in common with TimeInstantLayer
190
191 SparseTimeValueModel::PointList 181 SparseTimeValueModel::PointList
192 TimeValueLayer::getLocalPoints(int x) const 182 TimeValueLayer::getLocalPoints(int x) const
193 { 183 {
194 if (!m_model) return SparseTimeValueModel::PointList(); 184 if (!m_model) return SparseTimeValueModel::PointList();
195 185
220 } 210 }
221 211
222 return usePoints; 212 return usePoints;
223 } 213 }
224 214
225 void 215 QString
226 TimeValueLayer::paintLocalFeatureDescription(QPainter &paint, QRect rect, 216 TimeValueLayer::getFeatureDescription(QPoint &pos) const
227 QPoint pos) const 217 {
228 {
229 //!!! bleagh
230
231 int x = pos.x(); 218 int x = pos.x();
219
220 if (!m_model || !m_model->getSampleRate()) return "";
221
222 SparseTimeValueModel::PointList points = getLocalPoints(x);
223
224 if (points.empty()) {
225 if (!m_model->isReady()) {
226 return tr("In progress");
227 } else {
228 return tr("No local points");
229 }
230 }
231
232 long useFrame = points.begin()->frame;
233
234 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate());
232 235
233 if (!m_model || !m_model->getSampleRate()) return; 236 QString text;
234 237
235 SparseTimeValueModel::PointList points = getLocalPoints(x); 238 if (points.begin()->label == "") {
236 239 text = QString(tr("Time:\t%1\nValue:\t%2\nNo label"))
237 QFontMetrics metrics = paint.fontMetrics(); 240 .arg(rt.toText(true).c_str())
238 int xbase = rect.x() + 5; 241 .arg(points.begin()->value);
239 int ybase = rect.y() + 5; 242 } else {
240 243 text = QString(tr("Time:\t%1\nValue:\t%2\nLabel:\t%3"))
241 if (points.empty()) { 244 .arg(rt.toText(true).c_str())
242 QString label = tr("No local points"); 245 .arg(points.begin()->value)
243 if (!m_model->isReady()) { 246 .arg(points.begin()->label);
244 label = tr("In progress"); 247 }
245 } 248
246 paint.drawText(xbase + 5, ybase + 5 + metrics.ascent(), label); 249 pos = QPoint(getXForFrame(useFrame), getYForValue(points.begin()->value));
247 return; 250 return text;
248 }
249
250 long useFrame = points.begin()->frame;
251
252 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate());
253 QString timeText = QString("%1").arg(rt.toText(true).c_str());
254 QString valueText = QString("%1").arg(points.begin()->value);
255
256 int timewidth = metrics.width(timeText);
257 int valuewidth = metrics.width(valueText);
258 int labelwidth = metrics.width(points.begin()->label);
259
260 int boxheight = metrics.height() * 3 + 4;
261 int boxwidth = std::max(std::max(timewidth, labelwidth), valuewidth);
262
263 paint.drawRect(xbase, ybase, boxwidth + 10,
264 boxheight + 10 - metrics.descent() + 1);
265
266 paint.drawText(xbase + 5, ybase + 5 + metrics.ascent(), timeText);
267 paint.drawText(xbase + 5, ybase + 7 + metrics.ascent() + metrics.height(),
268 valueText);
269 paint.drawText(xbase + 5, ybase + 9 + metrics.ascent() + 2*metrics.height(),
270 points.begin()->label);
271 } 251 }
272 252
273 int 253 int
274 TimeValueLayer::getNearestFeatureFrame(int frame, 254 TimeValueLayer::getNearestFeatureFrame(int frame,
275 size_t &resolution, 255 size_t &resolution,