Mercurial > hg > svgui
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; |