Mercurial > hg > svgui
changeset 1539:bfacecf7ea7e
Overhaul choice of layer to show scale, in Pane::drawVerticalScale, making it call out to the same logic used by View::getVisibleExtentsForUnit when appropriate. Also refuse to accept scale from dormant top layer.
author | Chris Cannam |
---|---|
date | Tue, 15 Oct 2019 14:53:25 +0100 |
parents | 0ca4ca37809e |
children | 9ce6f69cd485 |
files | view/Pane.cpp view/View.cpp view/View.h |
diffstat | 3 files changed, 134 insertions(+), 102 deletions(-) [+] |
line wrap: on
line diff
--- a/view/Pane.cpp Tue Oct 15 14:51:58 2019 +0100 +++ b/view/Pane.cpp Tue Oct 15 14:53:25 2019 +0100 @@ -61,7 +61,8 @@ #include "widgets/KeyReference.h" //!!! should probably split KeyReference into a data class in base and another that shows the widget -//#define DEBUG_PANE +//#define DEBUG_PANE 1 +//#define DEBUG_PANE_SCALE_CHOICE 1 QCursor *Pane::m_measureCursor1 = nullptr; QCursor *Pane::m_measureCursor2 = nullptr; @@ -525,99 +526,120 @@ void Pane::drawVerticalScale(QRect r, Layer *topLayer, QPainter &paint) { - Layer *scaleLayer = nullptr; - -// cerr << "Pane::drawVerticalScale[" << this << "]" << endl; - double min, max; bool log; QString unit; - // If the top layer has no scale and reports no display extents, - // but does report a unit, then the scale should be drawn from any - // (visible) underlying layer with a scale and that unit. If the - // top layer has no scale and no value extents at all, then the - // scale should be drawn from any (visible) underlying layer with - // a scale regardless of unit. - - int sw = topLayer->getVerticalScaleWidth - (this, m_manager->shouldShowVerticalColourScale(), paint); + bool includeColourScale = m_manager->shouldShowVerticalColourScale(); - if (sw > 0) { + Layer *scaleLayer = nullptr; + int scaleWidth = 0; + + // If the topmost layer is prepared to draw a scale, then use it. + // + // Otherwise: find the topmost layer that has value extents, + // i.e. for which a scale is relevant at all. + // + // If that layer is prepared to draw a scale directly, then use + // it. This could be the case even if the layer has no unit and so + // does not participate in scale-providing / auto-align layers. + // + // Otherwise, request the scale-providing layer for that layer + // from the view, and if there is one and it can draw a scale, use + // that. + // + // In all cases ignore dormant layers, and if we hit an opaque + // layer before finding any with value extents, give up. + + if (topLayer && !topLayer->isLayerDormant(this)) { + scaleWidth = topLayer->getVerticalScaleWidth + (this, includeColourScale, paint); + +#ifdef DEBUG_PANE_SCALE_CHOICE + SVCERR << "Pane[" << getId() << "]::drawVerticalScale: Top layer (" + << topLayer << ") offers vertical scale width of " << scaleWidth + << endl; +#endif + } + + if (scaleWidth > 0) { scaleLayer = topLayer; - m_scaleWidth = sw; - } else { - bool hasDisplayExtents = topLayer->getDisplayExtents(min, max); - bool hasValueExtents = topLayer->getValueExtents(min, max, log, unit); - - if (!hasDisplayExtents) { - - if (!hasValueExtents) { - - for (LayerList::iterator vi = m_layerStack.end(); - vi != m_layerStack.begin(); ) { - - --vi; - - if ((*vi) == topLayer) continue; - if ((*vi)->isLayerDormant(this)) continue; - - sw = (*vi)->getVerticalScaleWidth - (this, m_manager->shouldShowVerticalColourScale(), paint); - - if (sw > 0) { - scaleLayer = *vi; - m_scaleWidth = sw; - break; - } - } - } else if (unit != "") { // && hasValueExtents && !hasDisplayExtents - - QString requireUnit = unit; - - for (LayerList::iterator vi = m_layerStack.end(); - vi != m_layerStack.begin(); ) { - - --vi; - - if ((*vi) == topLayer) continue; - if ((*vi)->isLayerDormant(this)) continue; - - if ((*vi)->getDisplayExtents(min, max)) { - - // search no further than this: if the - // scale from this layer isn't suitable, - // we'll have to draw no scale (else we'd - // risk ending up with the wrong scale) - - if ((*vi)->getValueExtents(min, max, log, unit) && - unit == requireUnit) { - - sw = (*vi)->getVerticalScaleWidth - (this, m_manager->shouldShowVerticalColourScale(), paint); - if (sw > 0) { - scaleLayer = *vi; - m_scaleWidth = sw; - } - } - break; - } - } + for (auto i = m_layerStack.rbegin(); i != m_layerStack.rend(); ++i) { + Layer *layer = *i; + + if (layer->isLayerDormant(this)) { +#ifdef DEBUG_PANE_SCALE_CHOICE + SVCERR << "Pane[" << getId() << "]::drawVerticalScale: " + << "Layer " << layer << " is dormant, skipping" << endl; +#endif + continue; + } + + if (layer->getValueExtents(min, max, log, unit)) { + scaleLayer = layer; + +#ifdef DEBUG_PANE_SCALE_CHOICE + SVCERR << "Pane[" << getId() << "]::drawVerticalScale: " + << "Layer " << layer << " has value extents (unit = " + << unit << "), using this layer or unit" << endl; +#endif + break; + } + + if (layer->isLayerOpaque()) { +#ifdef DEBUG_PANE + SVCERR << "Pane[" << getId() << "]::drawVerticalScale: " + << "Layer " << layer + << " is opaque, searching no further" << endl; +#endif + break; } } + + if (scaleLayer) { + scaleWidth = scaleLayer->getVerticalScaleWidth + (this, includeColourScale, paint); + +#ifdef DEBUG_PANE_SCALE_CHOICE + SVCERR << "Pane[" << getId() << "]::drawVerticalScale: Layer " + << topLayer << " offers vertical scale width of " + << scaleWidth << endl; +#endif + } + + if (scaleWidth == 0 && unit != "") { +#ifdef DEBUG_PANE_SCALE_CHOICE + SVDEBUG << "Pane[" << getId() + << "]::drawVerticalScale: No good scale layer, then, " + << "but we have a unit of " << unit + << " - seeking scale-providing layer for that" << endl; +#endif + + scaleLayer = getScaleProvidingLayerForUnit(unit); + +#ifdef DEBUG_PANE_SCALE_CHOICE + SVDEBUG << "Pane[" << getId() + << "]::drawVerticalScale: That returned " + << scaleLayer << endl; +#endif + } } - if (!scaleLayer) m_scaleWidth = 0; - -// cerr << "m_scaleWidth = " << m_scaleWidth << ", r.left = " << r.left() << endl; - + if (scaleWidth > 0) { + m_scaleWidth = scaleWidth; + } else if (scaleLayer) { + m_scaleWidth = scaleLayer->getVerticalScaleWidth + (this, includeColourScale, paint); + } else { + m_scaleWidth = 0; + } + if (m_scaleWidth > 0 && r.left() < m_scaleWidth) { // Profiler profiler("Pane::paintEvent - painting vertical scale", true); -// SVDEBUG << "Pane::paintEvent: calling paint.save() in vertical scale block" << endl; paint.save(); paint.setPen(Qt::NoPen); @@ -629,8 +651,8 @@ paint.setBrush(Qt::NoBrush); scaleLayer->paintVerticalScale - (this, m_manager->shouldShowVerticalColourScale(), - paint, QRect(0, 0, m_scaleWidth, height())); + (this, includeColourScale, paint, + QRect(0, 0, m_scaleWidth, height())); paint.restore(); }
--- a/view/View.cpp Tue Oct 15 14:51:58 2019 +0100 +++ b/view/View.cpp Tue Oct 15 14:53:25 2019 +0100 @@ -197,10 +197,34 @@ double &min, double &max, bool &log) const { - bool have = false; - - // Iterate in reverse order, so as to return display extents of - // topmost layer that fits the bill + 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; + } + } else { + return false; + } +} + +Layer * +View::getScaleProvidingLayerForUnit(QString unit) const +{ + // Iterate in reverse order, so as to use topmost layer that fits + // the bill for (auto i = m_layerStack.rbegin(); i != m_layerStack.rend(); ++i) { @@ -221,26 +245,10 @@ continue; } - double displayMin = 0.0, displayMax = 0.0; - - if (layer->getDisplayExtents(displayMin, displayMax)) { - - min = displayMin; - max = displayMax; - log = layerLog; - have = true; - break; - - } else { - - if (!have || layerMin < min) min = layerMin; - if (!have || layerMax > max) max = layerMax; - if (!have && layerLog) log = true; - have = true; - } + return layer; } - return have; + return nullptr; } bool
--- a/view/View.h Tue Oct 15 14:51:58 2019 +0100 +++ b/view/View.h Tue Oct 15 14:53:25 2019 +0100 @@ -502,6 +502,8 @@ LayerList getScrollableBackLayers(bool testChanged, bool &changed) const; LayerList getNonScrollableFrontLayers(bool testChanged, bool &changed) const; + Layer *getScaleProvidingLayerForUnit(QString unit) const; + ZoomLevel getZoomConstraintLevel(ZoomLevel level, ZoomConstraint::RoundingDirection dir = ZoomConstraint::RoundNearest) const;