comparison view/View.cpp @ 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 bfacecf7ea7e
children bd6af89982d7
comparison
equal deleted inserted replaced
1540:9ce6f69cd485 1541:b4b5b8dd5fe1
49 #include <cmath> 49 #include <cmath>
50 50
51 //#define DEBUG_VIEW 1 51 //#define DEBUG_VIEW 1
52 //#define DEBUG_VIEW_WIDGET_PAINT 1 52 //#define DEBUG_VIEW_WIDGET_PAINT 1
53 //#define DEBUG_PROGRESS_STUFF 1 53 //#define DEBUG_PROGRESS_STUFF 1
54 //#define DEBUG_VIEW_SCALE_CHOICE 1
54 55
55 View::View(QWidget *w, bool showProgress) : 56 View::View(QWidget *w, bool showProgress) :
56 QFrame(w), 57 QFrame(w),
57 m_id(getNextId()), 58 m_id(getNextId()),
58 m_centreFrame(0), 59 m_centreFrame(0),
195 bool 196 bool
196 View::getVisibleExtentsForUnit(QString unit, 197 View::getVisibleExtentsForUnit(QString unit,
197 double &min, double &max, 198 double &min, double &max,
198 bool &log) const 199 bool &log) const
199 { 200 {
201 #ifdef DEBUG_VIEW_SCALE_CHOICE
202 SVCERR << "View[" << getId() << "]::getVisibleExtentsForUnit("
203 << unit << ")" << endl;
204 #endif
205
200 Layer *layer = getScaleProvidingLayerForUnit(unit); 206 Layer *layer = getScaleProvidingLayerForUnit(unit);
201 if (!layer) {
202 return false;
203 }
204
205 //!!! clumsy
206 207
207 QString layerUnit; 208 QString layerUnit;
208 double layerMin, layerMax; 209 double layerMin, layerMax;
209 210
210 if (layer->getValueExtents(layerMin, layerMax, log, layerUnit)) { 211 if (!layer) {
211 if (layer->getDisplayExtents(min, max)) { 212 #ifdef DEBUG_VIEW_SCALE_CHOICE
212 return true; 213 SVCERR << "View[" << getId() << "]::getVisibleExtentsForUnit("
213 } else { 214 << unit << "): No scale-providing layer for this unit, "
214 min = layerMin; 215 << "taking union of extents of layers with this unit" << endl;
215 max = layerMax; 216 #endif
216 return true; 217 bool haveAny = false;
217 } 218 bool layerLog;
218 } else { 219 for (auto i = m_layerStack.rbegin(); i != m_layerStack.rend(); ++i) {
219 return false; 220 Layer *layer = *i;
220 } 221 if (layer->getValueExtents(layerMin, layerMax,
222 layerLog, layerUnit)) {
223 if (unit.toLower() != layerUnit.toLower()) {
224 continue;
225 }
226 if (!haveAny || layerMin < min) {
227 min = layerMin;
228 }
229 if (!haveAny || layerMax > max) {
230 max = layerMax;
231 }
232 if (!haveAny || layerLog) {
233 log = layerLog;
234 }
235 haveAny = true;
236 }
237 }
238 return haveAny;
239 }
240
241 return (layer->getValueExtents(layerMin, layerMax, log, layerUnit) &&
242 layer->getDisplayExtents(min, max));
221 } 243 }
222 244
223 Layer * 245 Layer *
224 View::getScaleProvidingLayerForUnit(QString unit) const 246 View::getScaleProvidingLayerForUnit(QString unit) const
225 { 247 {
226 // Iterate in reverse order, so as to use topmost layer that fits 248 // Return the layer which is used to provide the min/max/log for
227 // the bill 249 // any auto-align layer of a given unit. This is also the layer
250 // that will draw the scale, if possible. It is the topmost
251 // visible layer having that unit that is not also auto-aligning.
252 // If there is none such, return null.
228 253
229 for (auto i = m_layerStack.rbegin(); i != m_layerStack.rend(); ++i) { 254 for (auto i = m_layerStack.rbegin(); i != m_layerStack.rend(); ++i) {
230 255
231 Layer *layer = *i; 256 Layer *layer = *i;
232 257
258 #ifdef DEBUG_VIEW_SCALE_CHOICE
259 SVCERR << "View[" << getId() << "]::getScaleProvidingLayerForUnit("
260 << unit << "): Looking at layer " << layer
261 << " (" << layer->getLayerPresentationName() << ")" << endl;
262 #endif
263
233 if (layer->isLayerDormant(this)) { 264 if (layer->isLayerDormant(this)) {
265 #ifdef DEBUG_VIEW_SCALE_CHOICE
266 SVCERR << "... it's dormant" << endl;
267 #endif
234 continue; 268 continue;
235 } 269 }
236 270
237 QString layerUnit; 271 QString layerUnit;
238 double layerMin = 0.0, layerMax = 0.0; 272 double layerMin = 0.0, layerMax = 0.0;
239 bool layerLog = false; 273 bool layerLog = false;
240 274
241 if (!layer->getValueExtents(layerMin, layerMax, layerLog, layerUnit)) { 275 if (!layer->getValueExtents(layerMin, layerMax, layerLog, layerUnit)) {
276 #ifdef DEBUG_VIEW_SCALE_CHOICE
277 SVCERR << "... it has no value extents" << endl;
278 #endif
242 continue; 279 continue;
243 } 280 }
244 if (layerUnit.toLower() != unit.toLower()) { 281 if (layerUnit.toLower() != unit.toLower()) {
282 #ifdef DEBUG_VIEW_SCALE_CHOICE
283 SVCERR << "... it has the wrong unit (" << layerUnit << ")" << endl;
284 #endif
245 continue; 285 continue;
246 } 286 }
287
288 double displayMin = 0.0, displayMax = 0.0;
289 if (!layer->getDisplayExtents(displayMin, displayMax)) {
290 #ifdef DEBUG_VIEW_SCALE_CHOICE
291 SVCERR << "... it has no display extents (is auto-aligning or not alignable)" << endl;
292 #endif
293 continue;
294 }
295
296 #ifdef DEBUG_VIEW_SCALE_CHOICE
297 SVCERR << "... it's good" << endl;
298 #endif
247 299
248 return layer; 300 return layer;
249 } 301 }
250 302
251 return nullptr; 303 return nullptr;