Mercurial > hg > svgui
changeset 1541:b4b5b8dd5fe1
Fix getScaleProvidingLayerForUnit to make it only return a layer that actually has display extents. Modify getVisibleExtentsForUnit to make it more like the behaviour in 3.x: where no layer with display extents is found, use the union of the value extents of layers with the right unit. Partial fix for #1954 Peculiar alignment for Amplitude Follower y-scale in Auto-Align mode.
author | Chris Cannam |
---|---|
date | Wed, 16 Oct 2019 12:19:04 +0100 |
parents | 9ce6f69cd485 |
children | 10fe8124dc17 |
files | view/View.cpp |
diffstat | 1 files changed, 68 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/view/View.cpp Wed Oct 16 12:13:28 2019 +0100 +++ b/view/View.cpp Wed Oct 16 12:19:04 2019 +0100 @@ -51,6 +51,7 @@ //#define DEBUG_VIEW 1 //#define DEBUG_VIEW_WIDGET_PAINT 1 //#define DEBUG_PROGRESS_STUFF 1 +//#define DEBUG_VIEW_SCALE_CHOICE 1 View::View(QWidget *w, bool showProgress) : QFrame(w), @@ -197,40 +198,73 @@ double &min, double &max, bool &log) const { +#ifdef DEBUG_VIEW_SCALE_CHOICE + SVCERR << "View[" << getId() << "]::getVisibleExtentsForUnit(" + << unit << ")" << endl; +#endif + Layer *layer = getScaleProvidingLayerForUnit(unit); - if (!layer) { - return false; - } - - //!!! clumsy QString layerUnit; double layerMin, layerMax; - if (layer->getValueExtents(layerMin, layerMax, log, layerUnit)) { - if (layer->getDisplayExtents(min, max)) { - return true; - } else { - min = layerMin; - max = layerMax; - return true; + if (!layer) { +#ifdef DEBUG_VIEW_SCALE_CHOICE + SVCERR << "View[" << getId() << "]::getVisibleExtentsForUnit(" + << unit << "): No scale-providing layer for this unit, " + << "taking union of extents of layers with this unit" << endl; +#endif + bool haveAny = false; + bool layerLog; + for (auto i = m_layerStack.rbegin(); i != m_layerStack.rend(); ++i) { + Layer *layer = *i; + if (layer->getValueExtents(layerMin, layerMax, + layerLog, layerUnit)) { + if (unit.toLower() != layerUnit.toLower()) { + continue; + } + if (!haveAny || layerMin < min) { + min = layerMin; + } + if (!haveAny || layerMax > max) { + max = layerMax; + } + if (!haveAny || layerLog) { + log = layerLog; + } + haveAny = true; + } } - } else { - return false; + return haveAny; } + + return (layer->getValueExtents(layerMin, layerMax, log, layerUnit) && + layer->getDisplayExtents(min, max)); } Layer * View::getScaleProvidingLayerForUnit(QString unit) const { - // Iterate in reverse order, so as to use topmost layer that fits - // the bill + // Return the layer which is used to provide the min/max/log for + // any auto-align layer of a given unit. This is also the layer + // that will draw the scale, if possible. It is the topmost + // visible layer having that unit that is not also auto-aligning. + // If there is none such, return null. for (auto i = m_layerStack.rbegin(); i != m_layerStack.rend(); ++i) { Layer *layer = *i; +#ifdef DEBUG_VIEW_SCALE_CHOICE + SVCERR << "View[" << getId() << "]::getScaleProvidingLayerForUnit(" + << unit << "): Looking at layer " << layer + << " (" << layer->getLayerPresentationName() << ")" << endl; +#endif + if (layer->isLayerDormant(this)) { +#ifdef DEBUG_VIEW_SCALE_CHOICE + SVCERR << "... it's dormant" << endl; +#endif continue; } @@ -239,12 +273,30 @@ bool layerLog = false; if (!layer->getValueExtents(layerMin, layerMax, layerLog, layerUnit)) { +#ifdef DEBUG_VIEW_SCALE_CHOICE + SVCERR << "... it has no value extents" << endl; +#endif continue; } if (layerUnit.toLower() != unit.toLower()) { +#ifdef DEBUG_VIEW_SCALE_CHOICE + SVCERR << "... it has the wrong unit (" << layerUnit << ")" << endl; +#endif continue; } + double displayMin = 0.0, displayMax = 0.0; + if (!layer->getDisplayExtents(displayMin, displayMax)) { +#ifdef DEBUG_VIEW_SCALE_CHOICE + SVCERR << "... it has no display extents (is auto-aligning or not alignable)" << endl; +#endif + continue; + } + +#ifdef DEBUG_VIEW_SCALE_CHOICE + SVCERR << "... it's good" << endl; +#endif + return layer; }