Mercurial > hg > svcore
changeset 1552:05c3fbaec8ea
Introduce RelativelyFineZoomConstraint, which encodes more-or-less the scheme that was already used for the horizontal thumbwheel in the pane (which overrode the layers' own zoom constraints unless they said they couldn't support any other)
author | Chris Cannam |
---|---|
date | Wed, 10 Oct 2018 14:32:34 +0100 |
parents | 4de4284d0596 |
children | 66c1988fc906 |
files | base/ZoomConstraint.h data/model/PowerOfSqrtTwoZoomConstraint.cpp data/model/RelativelyFineZoomConstraint.cpp data/model/RelativelyFineZoomConstraint.h data/model/test/TestZoomConstraints.h files.pri |
diffstat | 6 files changed, 375 insertions(+), 113 deletions(-) [+] |
line wrap: on
line diff
--- a/base/ZoomConstraint.h Wed Oct 10 08:44:15 2018 +0100 +++ b/base/ZoomConstraint.h Wed Oct 10 14:32:34 2018 +0100 @@ -54,6 +54,10 @@ RoundingDirection = RoundNearest) const { + // canonicalise + if (requestedZoomLevel.level == 1) { + requestedZoomLevel.zone = ZoomLevel::FramesPerPixel; + } if (getMaxZoomLevel() < requestedZoomLevel) return getMaxZoomLevel(); else return requestedZoomLevel; }
--- a/data/model/PowerOfSqrtTwoZoomConstraint.cpp Wed Oct 10 08:44:15 2018 +0100 +++ b/data/model/PowerOfSqrtTwoZoomConstraint.cpp Wed Oct 10 14:32:34 2018 +0100 @@ -103,6 +103,7 @@ if (base == blockSize) { result = base; +// SVCERR << "Equal, accepting" << endl; break; } @@ -110,8 +111,12 @@ if (dir == RoundNearest) { if (base - blockSize < blockSize - prevBase) { dir = RoundUp; +// SVCERR << "Closer to " << base << " than " << prevBase +// << ", rounding up" << endl; } else { dir = RoundDown; +// SVCERR << "Closer to " << prevBase << " than " << base +// << ", rounding down" << endl; } } if (dir == RoundUp) { @@ -134,5 +139,7 @@ result = getMaxZoomLevel().level; } +// SVCERR << "Returning result " << result << endl; + return result; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/model/RelativelyFineZoomConstraint.cpp Wed Oct 10 14:32:34 2018 +0100 @@ -0,0 +1,101 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "RelativelyFineZoomConstraint.h" + +#include <vector> +#include <algorithm> +#include <iostream> + +using namespace std; + +ZoomLevel +RelativelyFineZoomConstraint::getNearestZoomLevel(ZoomLevel requested, + RoundingDirection dir) const +{ + static vector<int> levels; + + int maxLevel = getMaxZoomLevel().level; + + if (levels.empty()) { + int level = 1; + while (level <= maxLevel) { +// cerr << level << " "; + levels.push_back(level); + int step = level / 10; + int pwr = 0; + while (step > 0) { + ++pwr; + step /= 2; + } + step = (1 << pwr); + level += step; + } +// cerr << endl; + } + + RoundingDirection effective = dir; + if (requested.zone == ZoomLevel::PixelsPerFrame) { + if (dir == RoundUp) effective = RoundDown; + else if (dir == RoundDown) effective = RoundUp; + } + + // iterator pointing to first level that is >= requested + auto i = lower_bound(levels.begin(), levels.end(), requested.level); + + ZoomLevel newLevel(requested); + + if (i == levels.end()) { + newLevel.level = maxLevel; + + } else if (*i == requested.level) { + newLevel.level = requested.level; + + } else if (effective == RoundUp) { + newLevel.level = *i; + + } else if (effective == RoundDown) { + if (i != levels.begin()) { + --i; + } + newLevel.level = *i; + + } else { // RoundNearest + if (i != levels.begin()) { + auto j = i; + --j; + if (requested.level - *j < *i - requested.level) { + newLevel.level = *j; + } else { + newLevel.level = *i; + } + } + } + + // canonicalise + if (newLevel.level == 1) { + newLevel.zone = ZoomLevel::FramesPerPixel; + } + + using namespace std::rel_ops; + if (newLevel > getMaxZoomLevel()) { + newLevel = getMaxZoomLevel(); + } else if (newLevel < getMinZoomLevel()) { + newLevel = getMinZoomLevel(); + } + + return newLevel; +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/data/model/RelativelyFineZoomConstraint.h Wed Oct 10 14:32:34 2018 +0100 @@ -0,0 +1,29 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef SV_RELATIVELY_FINE_ZOOM_CONSTRAINT_H +#define SV_RELATIVELY_FINE_ZOOM_CONSTRAINT_H + +#include "base/ZoomConstraint.h" + +class RelativelyFineZoomConstraint : virtual public ZoomConstraint +{ +public: + virtual ZoomLevel getNearestZoomLevel(ZoomLevel requested, + RoundingDirection dir = RoundNearest) + const override; +}; + +#endif +
--- a/data/model/test/TestZoomConstraints.h Wed Oct 10 08:44:15 2018 +0100 +++ b/data/model/test/TestZoomConstraints.h Wed Oct 10 14:32:34 2018 +0100 @@ -17,6 +17,7 @@ #include "../PowerOfTwoZoomConstraint.h" #include "../PowerOfSqrtTwoZoomConstraint.h" +#include "../RelativelyFineZoomConstraint.h" #include <QObject> #include <QtTest> @@ -30,24 +31,90 @@ { Q_OBJECT + string roundingName(ZoomConstraint::RoundingDirection dir) { + switch (dir) { + case ZoomConstraint::RoundDown: return "RoundDown"; + case ZoomConstraint::RoundUp: return "RoundUp"; + case ZoomConstraint::RoundNearest: return "RoundNearest"; + } + return "<?>"; + } + + void compare(ZoomLevel zin, + ZoomConstraint::RoundingDirection dir, + ZoomLevel zobt, + ZoomLevel zexp) { + if (zexp.level == 1) { + // A zoom level of "1 pixel per frame" is not considered + // canonical - it should be "1 frame per pixel" + zexp.zone = ZoomLevel::FramesPerPixel; + } + if (zobt == zexp) { + return; + } else { + cerr << "For input " << zin << " and rounding direction " + << roundingName(dir) + << ", expected output " << zexp << " but obtained " << zobt + << endl; + QCOMPARE(zobt, zexp); + } + } + void checkFpp(const ZoomConstraint &c, ZoomConstraint::RoundingDirection dir, int n, int expected) { - QCOMPARE(c.getNearestZoomLevel(ZoomLevel(ZoomLevel::FramesPerPixel, n), - dir), - ZoomLevel(ZoomLevel::FramesPerPixel, expected)); + ZoomLevel zin(ZoomLevel::FramesPerPixel, n); + ZoomLevel zexp(ZoomLevel::FramesPerPixel, expected); + ZoomLevel zobt(c.getNearestZoomLevel(zin, dir)); + compare(zin, dir, zobt, zexp); } - + + void checkPpf(const ZoomConstraint &c, + ZoomConstraint::RoundingDirection dir, + int n, + int expected) { + ZoomLevel zin(ZoomLevel::PixelsPerFrame, n); + ZoomLevel zexp(ZoomLevel::PixelsPerFrame, expected); + ZoomLevel zobt(c.getNearestZoomLevel(zin, dir)); + compare(zin, dir, zobt, zexp); + } + + void checkBoth(const ZoomConstraint &c, + ZoomConstraint::RoundingDirection dir, + int n, + int expected) { + checkFpp(c, dir, n, expected); + checkPpf(c, dir, n, expected); + } + + void checkMaxMin(const ZoomConstraint &c, + ZoomConstraint::RoundingDirection dir) { + auto max = c.getMaxZoomLevel(); + compare(max, dir, + c.getNearestZoomLevel(max, dir), max); + compare(max.incremented(), dir, + c.getNearestZoomLevel(max.incremented(), dir), max); + auto min = c.getMinZoomLevel(); + compare(min, dir, + c.getNearestZoomLevel(min, dir), min); + compare(min.decremented(), dir, + c.getNearestZoomLevel(min.decremented(), dir), min); + } + + const static ZoomConstraint::RoundingDirection up = ZoomConstraint::RoundUp; + const static ZoomConstraint::RoundingDirection down = ZoomConstraint::RoundDown; + const static ZoomConstraint::RoundingDirection nearest = ZoomConstraint::RoundNearest; + private slots: void unconstrainedNearest() { ZoomConstraint c; - checkFpp(c, ZoomConstraint::RoundNearest, 1, 1); - checkFpp(c, ZoomConstraint::RoundNearest, 2, 2); - checkFpp(c, ZoomConstraint::RoundNearest, 3, 3); - checkFpp(c, ZoomConstraint::RoundNearest, 4, 4); - checkFpp(c, ZoomConstraint::RoundNearest, 20, 20); - checkFpp(c, ZoomConstraint::RoundNearest, 32, 32); + checkBoth(c, nearest, 1, 1); + checkBoth(c, nearest, 2, 2); + checkBoth(c, nearest, 3, 3); + checkBoth(c, nearest, 4, 4); + checkBoth(c, nearest, 20, 20); + checkBoth(c, nearest, 32, 32); auto max = c.getMaxZoomLevel(); QCOMPARE(c.getNearestZoomLevel(max), max); QCOMPARE(c.getNearestZoomLevel(max.incremented()), max); @@ -55,44 +122,40 @@ void unconstrainedUp() { ZoomConstraint c; - checkFpp(c, ZoomConstraint::RoundUp, 1, 1); - checkFpp(c, ZoomConstraint::RoundUp, 2, 2); - checkFpp(c, ZoomConstraint::RoundUp, 3, 3); - checkFpp(c, ZoomConstraint::RoundUp, 4, 4); - checkFpp(c, ZoomConstraint::RoundUp, 20, 20); - checkFpp(c, ZoomConstraint::RoundUp, 32, 32); + checkBoth(c, up, 1, 1); + checkBoth(c, up, 2, 2); + checkBoth(c, up, 3, 3); + checkBoth(c, up, 4, 4); + checkBoth(c, up, 20, 20); + checkBoth(c, up, 32, 32); auto max = c.getMaxZoomLevel(); - QCOMPARE(c.getNearestZoomLevel(max, - ZoomConstraint::RoundUp), max); - QCOMPARE(c.getNearestZoomLevel(max.incremented(), - ZoomConstraint::RoundUp), max); + QCOMPARE(c.getNearestZoomLevel(max, up), max); + QCOMPARE(c.getNearestZoomLevel(max.incremented(), up), max); } void unconstrainedDown() { ZoomConstraint c; - checkFpp(c, ZoomConstraint::RoundDown, 1, 1); - checkFpp(c, ZoomConstraint::RoundDown, 2, 2); - checkFpp(c, ZoomConstraint::RoundDown, 3, 3); - checkFpp(c, ZoomConstraint::RoundDown, 4, 4); - checkFpp(c, ZoomConstraint::RoundDown, 20, 20); - checkFpp(c, ZoomConstraint::RoundDown, 32, 32); + checkBoth(c, down, 1, 1); + checkBoth(c, down, 2, 2); + checkBoth(c, down, 3, 3); + checkBoth(c, down, 4, 4); + checkBoth(c, down, 20, 20); + checkBoth(c, down, 32, 32); auto max = c.getMaxZoomLevel(); - QCOMPARE(c.getNearestZoomLevel(max, - ZoomConstraint::RoundDown), max); - QCOMPARE(c.getNearestZoomLevel(max.incremented(), - ZoomConstraint::RoundDown), max); + QCOMPARE(c.getNearestZoomLevel(max, down), max); + QCOMPARE(c.getNearestZoomLevel(max.incremented(), down), max); } void powerOfTwoNearest() { PowerOfTwoZoomConstraint c; - checkFpp(c, ZoomConstraint::RoundNearest, 1, 1); - checkFpp(c, ZoomConstraint::RoundNearest, 2, 2); - checkFpp(c, ZoomConstraint::RoundNearest, 3, 2); - checkFpp(c, ZoomConstraint::RoundNearest, 4, 4); - checkFpp(c, ZoomConstraint::RoundNearest, 20, 16); - checkFpp(c, ZoomConstraint::RoundNearest, 23, 16); - checkFpp(c, ZoomConstraint::RoundNearest, 24, 16); - checkFpp(c, ZoomConstraint::RoundNearest, 25, 32); + checkBoth(c, nearest, 1, 1); + checkBoth(c, nearest, 2, 2); + checkBoth(c, nearest, 3, 2); + checkBoth(c, nearest, 4, 4); + checkBoth(c, nearest, 20, 16); + checkBoth(c, nearest, 23, 16); + checkBoth(c, nearest, 24, 16); + checkBoth(c, nearest, 25, 32); auto max = c.getMaxZoomLevel(); QCOMPARE(c.getNearestZoomLevel(max), max); QCOMPARE(c.getNearestZoomLevel(max.incremented()), max); @@ -100,101 +163,157 @@ void powerOfTwoUp() { PowerOfTwoZoomConstraint c; - checkFpp(c, ZoomConstraint::RoundUp, 1, 1); - checkFpp(c, ZoomConstraint::RoundUp, 2, 2); - checkFpp(c, ZoomConstraint::RoundUp, 3, 4); - checkFpp(c, ZoomConstraint::RoundUp, 4, 4); - checkFpp(c, ZoomConstraint::RoundUp, 20, 32); - checkFpp(c, ZoomConstraint::RoundUp, 32, 32); - checkFpp(c, ZoomConstraint::RoundUp, 33, 64); - auto max = c.getMaxZoomLevel(); - QCOMPARE(c.getNearestZoomLevel(max, - ZoomConstraint::RoundUp), max); - QCOMPARE(c.getNearestZoomLevel(max.incremented(), - ZoomConstraint::RoundUp), max); + checkBoth(c, up, 1, 1); + checkBoth(c, up, 2, 2); + checkFpp(c, up, 3, 4); + checkPpf(c, up, 3, 2); + checkBoth(c, up, 4, 4); + checkFpp(c, up, 20, 32); + checkPpf(c, up, 20, 16); + checkBoth(c, up, 32, 32); + checkFpp(c, up, 33, 64); + checkPpf(c, up, 33, 32); + checkMaxMin(c, up); } void powerOfTwoDown() { PowerOfTwoZoomConstraint c; - checkFpp(c, ZoomConstraint::RoundDown, 1, 1); - checkFpp(c, ZoomConstraint::RoundDown, 2, 2); - checkFpp(c, ZoomConstraint::RoundDown, 3, 2); - checkFpp(c, ZoomConstraint::RoundDown, 4, 4); - checkFpp(c, ZoomConstraint::RoundDown, 20, 16); - checkFpp(c, ZoomConstraint::RoundDown, 32, 32); - checkFpp(c, ZoomConstraint::RoundDown, 33, 32); - auto max = c.getMaxZoomLevel(); - QCOMPARE(c.getNearestZoomLevel(max, - ZoomConstraint::RoundDown), max); - QCOMPARE(c.getNearestZoomLevel(max.incremented(), - ZoomConstraint::RoundDown), max); + checkBoth(c, down, 1, 1); + checkBoth(c, down, 2, 2); + checkFpp(c, down, 3, 2); + checkPpf(c, down, 3, 4); + checkBoth(c, down, 4, 4); + checkFpp(c, down, 20, 16); + checkPpf(c, down, 20, 32); + checkBoth(c, down, 32, 32); + checkFpp(c, down, 33, 32); + checkPpf(c, down, 33, 64); + checkMaxMin(c, down); } void powerOfSqrtTwoNearest() { PowerOfSqrtTwoZoomConstraint c; - checkFpp(c, ZoomConstraint::RoundNearest, 1, 1); - checkFpp(c, ZoomConstraint::RoundNearest, 2, 2); - checkFpp(c, ZoomConstraint::RoundNearest, 3, 2); - checkFpp(c, ZoomConstraint::RoundNearest, 4, 4); - checkFpp(c, ZoomConstraint::RoundNearest, 18, 16); - checkFpp(c, ZoomConstraint::RoundNearest, 19, 16); - checkFpp(c, ZoomConstraint::RoundNearest, 20, 22); - checkFpp(c, ZoomConstraint::RoundNearest, 23, 22); - checkFpp(c, ZoomConstraint::RoundNearest, 28, 32); + checkBoth(c, nearest, 1, 1); + checkBoth(c, nearest, 2, 2); + checkBoth(c, nearest, 3, 2); + checkBoth(c, nearest, 4, 4); + checkBoth(c, nearest, 18, 16); + checkBoth(c, nearest, 19, 16); + checkBoth(c, nearest, 20, 22); + checkBoth(c, nearest, 23, 22); + checkBoth(c, nearest, 28, 32); // PowerOfSqrtTwoZoomConstraint makes an effort to ensure // bigger numbers get rounded to a multiple of something // simple (64 or 90 depending on whether they are power-of-two // or power-of-sqrt-two types) - checkFpp(c, ZoomConstraint::RoundNearest, 800, 720); - checkFpp(c, ZoomConstraint::RoundNearest, 1023, 1024); - checkFpp(c, ZoomConstraint::RoundNearest, 1024, 1024); - checkFpp(c, ZoomConstraint::RoundNearest, 1024, 1024); - checkFpp(c, ZoomConstraint::RoundNearest, 1025, 1024); - auto max = c.getMaxZoomLevel(); - QCOMPARE(c.getNearestZoomLevel(max), max); - QCOMPARE(c.getNearestZoomLevel(max.incremented()), max); + checkBoth(c, nearest, 350, 360); + // The most extreme level available in ppf mode + // (getMinZoomLevel()) is currently 512, so these bigger + // numbers will only happen in fpp mode + checkFpp(c, nearest, 800, 720); + checkFpp(c, nearest, 1023, 1024); + checkFpp(c, nearest, 1024, 1024); + checkFpp(c, nearest, 1024, 1024); + checkFpp(c, nearest, 1025, 1024); + checkPpf(c, nearest, 800, 512); + checkPpf(c, nearest, 1025, 512); + checkMaxMin(c, nearest); } void powerOfSqrtTwoUp() { PowerOfSqrtTwoZoomConstraint c; - checkFpp(c, ZoomConstraint::RoundUp, 1, 1); - checkFpp(c, ZoomConstraint::RoundUp, 2, 2); - checkFpp(c, ZoomConstraint::RoundUp, 3, 4); - checkFpp(c, ZoomConstraint::RoundUp, 4, 4); - checkFpp(c, ZoomConstraint::RoundUp, 18, 22); - checkFpp(c, ZoomConstraint::RoundUp, 22, 22); - checkFpp(c, ZoomConstraint::RoundUp, 23, 32); - checkFpp(c, ZoomConstraint::RoundUp, 800, 1024); - checkFpp(c, ZoomConstraint::RoundUp, 1023, 1024); - checkFpp(c, ZoomConstraint::RoundUp, 1024, 1024); - // see comment above - checkFpp(c, ZoomConstraint::RoundUp, 1025, 1440); - auto max = c.getMaxZoomLevel(); - QCOMPARE(c.getNearestZoomLevel(max, - ZoomConstraint::RoundUp), max); - QCOMPARE(c.getNearestZoomLevel(max.incremented(), - ZoomConstraint::RoundUp), max); + checkBoth(c, up, 1, 1); + checkBoth(c, up, 2, 2); + checkFpp(c, up, 3, 4); + checkPpf(c, up, 3, 2); + checkBoth(c, up, 4, 4); + checkFpp(c, up, 18, 22); + checkPpf(c, up, 18, 16); + checkBoth(c, up, 22, 22); + checkFpp(c, up, 23, 32); + checkPpf(c, up, 23, 22); + // see comments above + checkFpp(c, up, 800, 1024); + checkFpp(c, up, 1023, 1024); + checkFpp(c, up, 1024, 1024); + checkFpp(c, up, 1025, 1440); + checkPpf(c, up, 300, 256); + checkPpf(c, up, 800, 512); + checkPpf(c, up, 1600, 512); + checkMaxMin(c, up); } void powerOfSqrtTwoDown() { PowerOfSqrtTwoZoomConstraint c; - checkFpp(c, ZoomConstraint::RoundDown, 1, 1); - checkFpp(c, ZoomConstraint::RoundDown, 2, 2); - checkFpp(c, ZoomConstraint::RoundDown, 3, 2); - checkFpp(c, ZoomConstraint::RoundDown, 4, 4); - checkFpp(c, ZoomConstraint::RoundDown, 18, 16); - checkFpp(c, ZoomConstraint::RoundDown, 22, 22); - checkFpp(c, ZoomConstraint::RoundDown, 23, 22); - // see comment above - checkFpp(c, ZoomConstraint::RoundDown, 800, 720); - checkFpp(c, ZoomConstraint::RoundDown, 1023, 720); - checkFpp(c, ZoomConstraint::RoundDown, 1024, 1024); - checkFpp(c, ZoomConstraint::RoundDown, 1025, 1024); - auto max = c.getMaxZoomLevel(); - QCOMPARE(c.getNearestZoomLevel(max, - ZoomConstraint::RoundDown), max); - QCOMPARE(c.getNearestZoomLevel(max.incremented(), - ZoomConstraint::RoundDown), max); + checkBoth(c, down, 1, 1); + checkBoth(c, down, 2, 2); + checkFpp(c, down, 3, 2); + checkPpf(c, down, 3, 4); + checkBoth(c, down, 4, 4); + checkFpp(c, down, 18, 16); + checkPpf(c, down, 18, 22); + checkBoth(c, down, 22, 22); + checkFpp(c, down, 23, 22); + checkPpf(c, down, 23, 32); + // see comments above + checkFpp(c, down, 800, 720); + checkFpp(c, down, 1023, 720); + checkFpp(c, down, 1024, 1024); + checkFpp(c, down, 1025, 1024); + checkPpf(c, down, 300, 360); + checkPpf(c, down, 800, 512); + checkPpf(c, down, 1600, 512); + checkMaxMin(c, down); + } + + void relativelyFineNearest() { + RelativelyFineZoomConstraint c; + checkBoth(c, nearest, 1, 1); + checkBoth(c, nearest, 2, 2); + checkBoth(c, nearest, 3, 3); + checkBoth(c, nearest, 4, 4); + checkBoth(c, nearest, 20, 20); + checkBoth(c, nearest, 33, 32); + checkBoth(c, nearest, 59, 56); + checkBoth(c, nearest, 69, 72); + checkBoth(c, nearest, 121, 128); + checkMaxMin(c, nearest); + } + + void relativelyFineUp() { + RelativelyFineZoomConstraint c; + checkBoth(c, up, 1, 1); + checkBoth(c, up, 2, 2); + checkBoth(c, up, 3, 3); + checkBoth(c, up, 4, 4); + checkBoth(c, up, 20, 20); + checkFpp(c, up, 33, 36); + checkPpf(c, up, 33, 32); + checkFpp(c, up, 59, 64); + checkPpf(c, up, 59, 56); + checkFpp(c, up, 69, 72); + checkPpf(c, up, 69, 64); + checkFpp(c, up, 121, 128); + checkPpf(c, up, 121, 112); + checkMaxMin(c, up); + } + + void relativelyFineDown() { + RelativelyFineZoomConstraint c; + checkBoth(c, down, 1, 1); + checkBoth(c, down, 2, 2); + checkBoth(c, down, 3, 3); + checkBoth(c, down, 4, 4); + checkBoth(c, down, 20, 20); + checkFpp(c, down, 33, 32); + checkPpf(c, down, 33, 36); + checkFpp(c, down, 59, 56); + checkPpf(c, down, 59, 64); + checkFpp(c, down, 69, 64); + checkPpf(c, down, 69, 72); + checkFpp(c, down, 121, 112); + checkPpf(c, down, 121, 128); + checkMaxMin(c, down); } };
--- a/files.pri Wed Oct 10 08:44:15 2018 +0100 +++ b/files.pri Wed Oct 10 14:32:34 2018 +0100 @@ -90,6 +90,7 @@ data/model/PowerOfTwoZoomConstraint.h \ data/model/RangeSummarisableTimeValueModel.h \ data/model/RegionModel.h \ + data/model/RelativelyFineZoomConstraint.h \ data/model/SparseModel.h \ data/model/SparseOneDimensionalModel.h \ data/model/SparseTimeValueModel.h \ @@ -212,6 +213,7 @@ data/model/PowerOfSqrtTwoZoomConstraint.cpp \ data/model/PowerOfTwoZoomConstraint.cpp \ data/model/RangeSummarisableTimeValueModel.cpp \ + data/model/RelativelyFineZoomConstraint.cpp \ data/model/WaveformOversampler.cpp \ data/model/WaveFileModel.cpp \ data/model/ReadOnlyWaveFileModel.cpp \