comparison layer/TimeValueLayer.cpp @ 437:755243c67f59

* Add vertical zoom and pan to time-value layer. Still some defects, particularly in logarithmic mode. Now need to get this in note layer as well! * Some fixes to log colouring in segmentation mode of time-value layer.
author Chris Cannam
date Fri, 24 Oct 2008 14:52:40 +0000
parents 6324461340b1
children 76cd1c89eb06
comparison
equal deleted inserted replaced
436:1e0744b2cebe 437:755243c67f59
17 17
18 #include "data/model/Model.h" 18 #include "data/model/Model.h"
19 #include "base/RealTime.h" 19 #include "base/RealTime.h"
20 #include "base/Profiler.h" 20 #include "base/Profiler.h"
21 #include "base/LogRange.h" 21 #include "base/LogRange.h"
22 #include "base/RangeMapper.h"
22 #include "ColourDatabase.h" 23 #include "ColourDatabase.h"
23 #include "view/View.h" 24 #include "view/View.h"
24 25
25 #include "data/model/SparseTimeValueModel.h" 26 #include "data/model/SparseTimeValueModel.h"
26 #include "data/model/Labeller.h" 27 #include "data/model/Labeller.h"
49 m_originalPoint(0, 0.0, tr("New Point")), 50 m_originalPoint(0, 0.0, tr("New Point")),
50 m_editingPoint(0, 0.0, tr("New Point")), 51 m_editingPoint(0, 0.0, tr("New Point")),
51 m_editingCommand(0), 52 m_editingCommand(0),
52 m_colourMap(0), 53 m_colourMap(0),
53 m_plotStyle(PlotConnectedPoints), 54 m_plotStyle(PlotConnectedPoints),
54 m_verticalScale(AutoAlignScale) 55 m_verticalScale(AutoAlignScale),
56 m_scaleMinimum(0),
57 m_scaleMaximum(0)
55 { 58 {
56 59
57 } 60 }
58 61
59 void 62 void
258 bool 261 bool
259 TimeValueLayer::getDisplayExtents(float &min, float &max) const 262 TimeValueLayer::getDisplayExtents(float &min, float &max) const
260 { 263 {
261 if (!m_model || shouldAutoAlign()) return false; 264 if (!m_model || shouldAutoAlign()) return false;
262 265
263 min = m_model->getValueMinimum(); 266 if (m_scaleMinimum == m_scaleMaximum) {
264 max = m_model->getValueMaximum(); 267 m_scaleMinimum = m_model->getValueMinimum();
268 m_scaleMaximum = m_model->getValueMaximum();
269 }
270
271 min = m_scaleMinimum;
272 max = m_scaleMaximum;
273
274 // std::cerr << "TimeValueLayer::getDisplayExtents: min = " << min << ", max = " << max << std::endl;
275
265 return true; 276 return true;
277 }
278
279 bool
280 TimeValueLayer::setDisplayExtents(float min, float max)
281 {
282 if (!m_model) return false;
283
284 if (min == max) {
285 if (min == 0.f) {
286 max = 1.f;
287 } else {
288 max = min * 1.0001;
289 }
290 }
291
292 m_scaleMinimum = min;
293 m_scaleMaximum = max;
294
295 std::cerr << "TimeValueLayer::setDisplayExtents: min = " << min << ", max = " << max << std::endl;
296
297 emit layerParametersChanged();
298 return true;
299 }
300
301 int
302 TimeValueLayer::getVerticalZoomSteps(int &defaultStep) const
303 {
304 if (shouldAutoAlign()) return 0;
305 if (!m_model) return 0;
306
307 defaultStep = 100;
308 return 100;
309 }
310
311 int
312 TimeValueLayer::getCurrentVerticalZoomStep() const
313 {
314 if (shouldAutoAlign()) return 0;
315 if (!m_model) return 0;
316
317 RangeMapper *mapper = getNewVerticalZoomRangeMapper();
318 if (!mapper) return 0;
319
320 float dmin, dmax;
321 getDisplayExtents(dmin, dmax);
322
323 int nr = mapper->getPositionForValue(dmax - dmin);
324 /*
325 int n0 = mapper->getPositionForValue(dmax);
326 int n1 = mapper->getPositionForValue(dmin);
327 int nr = n1 - n0;
328 if (nr < 0) nr = -nr;
329
330 std::cerr << "TimeValueLayer::getCurrentVerticalZoomStep: dmin = " << dmin << ", dmax = " << dmax << ", n0 = " << n0 << ", n1 = " << n1 << ", nr = " << nr << std::endl;
331 */
332 delete mapper;
333
334 return 100 - nr;
335 }
336
337 void
338 TimeValueLayer::setVerticalZoomStep(int step)
339 {
340 if (shouldAutoAlign()) return;
341 if (!m_model) return;
342
343 RangeMapper *mapper = getNewVerticalZoomRangeMapper();
344 if (!mapper) return;
345
346 float min, max;
347 bool logarithmic;
348 QString unit;
349 getValueExtents(min, max, logarithmic, unit);
350
351 float dmin, dmax;
352 getDisplayExtents(dmin, dmax);
353
354 float newdist = mapper->getValueForPosition(100 - step);
355
356 float newmin, newmax;
357
358 if (logarithmic) {
359
360 // see SpectrogramLayer::setVerticalZoomStep
361
362 newmax = (newdist + sqrtf(newdist*newdist + 4*dmin*dmax)) / 2;
363 newmin = newmax - newdist;
364
365 // std::cerr << "newmin = " << newmin << ", newmax = " << newmax << std::endl;
366
367 } else {
368 float dmid = (dmax + dmin) / 2;
369 newmin = dmid - newdist / 2;
370 newmax = dmid + newdist / 2;
371 }
372
373 if (newmin < min) {
374 newmax += (min - newmin);
375 newmin = min;
376 }
377 if (newmax > max) {
378 newmax = max;
379 }
380
381 std::cerr << "TimeValueLayer::setVerticalZoomStep: " << step << ": " << newmin << " -> " << newmax << " (range " << newdist << ")" << std::endl;
382
383 setDisplayExtents(newmin, newmax);
384 }
385
386 RangeMapper *
387 TimeValueLayer::getNewVerticalZoomRangeMapper() const
388 {
389 if (!m_model) return 0;
390
391 RangeMapper *mapper;
392
393 float min, max;
394 bool logarithmic;
395 QString unit;
396 getValueExtents(min, max, logarithmic, unit);
397
398 if (min == max) return 0;
399
400 if (logarithmic) {
401 mapper = new LogRangeMapper(0, 100, min, max, unit);
402 } else {
403 mapper = new LinearRangeMapper(0, 100, min, max, unit);
404 }
405
406 return mapper;
266 } 407 }
267 408
268 SparseTimeValueModel::PointList 409 SparseTimeValueModel::PointList
269 TimeValueLayer::getLocalPoints(View *v, int x) const 410 TimeValueLayer::getLocalPoints(View *v, int x) const
270 { 411 {
444 min = -1.0; 585 min = -1.0;
445 max = 1.0; 586 max = 1.0;
446 587
447 } else { 588 } else {
448 589
449 min = m_model->getValueMinimum(); 590 getDisplayExtents(min, max);
450 max = m_model->getValueMaximum();
451 591
452 if (m_verticalScale == LogScale) { 592 if (m_verticalScale == LogScale) {
453 LogRange::mapRange(min, max); 593 LogRange::mapRange(min, max);
454 log = true; 594 log = true;
455 } 595 }
487 getScaleExtents(v, min, max, logarithmic); 627 getScaleExtents(v, min, max, logarithmic);
488 628
489 float val = min + (float(h - y) * float(max - min)) / h; 629 float val = min + (float(h - y) * float(max - min)) / h;
490 630
491 if (logarithmic) { 631 if (logarithmic) {
492 val = powf(10.f, val); 632 val = LogRange::map(val);
493 } 633 }
494 634
495 return val; 635 return val;
496 } 636 }
497 637
512 652
513 if (min > max) std::swap(min, max); 653 if (min > max) std::swap(min, max);
514 if (max == min) max = min + 1; 654 if (max == min) max = min + 1;
515 655
516 if (log) { 656 if (log) {
517 LogRange::mapRange(min, max);
518 val = LogRange::map(val); 657 val = LogRange::map(val);
519 } 658 }
520 659
521 // std::cerr << "TimeValueLayer::getColourForValue: min " << min << ", max " 660 // std::cerr << "TimeValueLayer::getColourForValue: min " << min << ", max "
522 // << max << ", log " << log << ", value " << val << std::endl; 661 // << max << ", log " << log << ", value " << val << std::endl;
779 918
780 int h = v->height(); 919 int h = v->height();
781 920
782 int n = 10; 921 int n = 10;
783 922
784 float max = m_model->getValueMaximum(); 923 float min, max;
785 float min = m_model->getValueMinimum(); 924 bool logarithmic;
925 getScaleExtents(v, min, max, logarithmic);
926
927 if (m_plotStyle == PlotSegmentation) {
928 QString unit;
929 getValueExtents(min, max, logarithmic, unit);
930 if (logarithmic) {
931 LogRange::mapRange(min, max);
932 }
933 }
934
786 float val = min; 935 float val = min;
787 float inc = (max - val) / n; 936 float inc = (max - val) / n;
788 937
789 char buffer[40]; 938 char buffer[40];
790 939
805 954
806 if (m_plotStyle == PlotSegmentation) { 955 if (m_plotStyle == PlotSegmentation) {
807 paint.save(); 956 paint.save();
808 for (int y = 0; y < boxh; ++y) { 957 for (int y = 0; y < boxh; ++y) {
809 float val = ((boxh - y) * (max - min)) / boxh + min; 958 float val = ((boxh - y) * (max - min)) / boxh + min;
810 paint.setPen(getColourForValue(v, val)); 959 if (logarithmic) {
960 paint.setPen(getColourForValue(v, LogRange::unmap(val)));
961 } else {
962 paint.setPen(getColourForValue(v, val));
963 }
811 paint.drawLine(boxx + 1, y + boxy + 1, boxx + boxw, y + boxy + 1); 964 paint.drawLine(boxx + 1, y + boxy + 1, boxx + boxw, y + boxy + 1);
812 } 965 }
813 paint.restore(); 966 paint.restore();
814 } 967 }
815 968
834 987
835 if (m_plotStyle == PlotSegmentation) { 988 if (m_plotStyle == PlotSegmentation) {
836 y = boxy + int(boxh - ((val - min) * boxh) / (max - min)); 989 y = boxy + int(boxh - ((val - min) * boxh) / (max - min));
837 ty = y; 990 ty = y;
838 } else { 991 } else {
839 if (i == n-1) { 992 if (i == n-1 &&
993 v->height() < paint.fontMetrics().height() * (n*2)) {
840 if (m_model->getScaleUnits() != "") drawText = false; 994 if (m_model->getScaleUnits() != "") drawText = false;
841 } 995 }
842 dispval = lrintf(val / round) * round; 996 dispval = lrintf(val / round) * round;
843 // std::cerr << "val = " << val << ", dispval = " << dispval << std::endl; 997 // std::cerr << "val = " << val << ", dispval = " << dispval << std::endl;
844 y = getYForValue(v, dispval); 998 if (logarithmic) {
999 y = getYForValue(v, LogRange::unmap(dispval));
1000 } else {
1001 y = getYForValue(v, dispval);
1002 }
845 ty = y - paint.fontMetrics().height() + 1003 ty = y - paint.fontMetrics().height() +
846 paint.fontMetrics().ascent() + 2; 1004 paint.fontMetrics().ascent() + 2;
847 1005
848 if (prevy >= 0 && (prevy - y) < paint.fontMetrics().height()) { 1006 if (prevy >= 0 && (prevy - y) < paint.fontMetrics().height()) {
849 val += inc; 1007 val += inc;
850 continue; 1008 continue;
851 } 1009 }
852 } 1010 }
853 1011
854 sprintf(buffer, "%.*f", dp, dispval); 1012 if (logarithmic) {
1013 sprintf(buffer, "%.*g", dp < 2 ? 2 : dp, LogRange::unmap(dispval));
1014 } else {
1015 sprintf(buffer, "%.*f", dp, dispval);
1016 }
855 QString label = QString(buffer); 1017 QString label = QString(buffer);
856 1018
857 if (m_plotStyle != PlotSegmentation) { 1019 if (m_plotStyle != PlotSegmentation) {
858 paint.drawLine(w - 5, y, w, y); 1020 paint.drawLine(w - 5, y, w, y);
859 } else { 1021 } else {