| Chris@1118 | 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */ | 
| Chris@1118 | 2 | 
| Chris@1118 | 3 /* | 
| Chris@1118 | 4     Sonic Visualiser | 
| Chris@1118 | 5     An audio file viewer and annotation editor. | 
| Chris@1118 | 6     Centre for Digital Music, Queen Mary, University of London. | 
| Chris@1118 | 7 | 
| Chris@1118 | 8     This program is free software; you can redistribute it and/or | 
| Chris@1118 | 9     modify it under the terms of the GNU General Public License as | 
| Chris@1118 | 10     published by the Free Software Foundation; either version 2 of the | 
| Chris@1118 | 11     License, or (at your option) any later version.  See the file | 
| Chris@1118 | 12     COPYING included with this distribution for more information. | 
| Chris@1118 | 13 */ | 
| Chris@1118 | 14 | 
| Chris@1118 | 15 #include "ScrollableMagRangeCache.h" | 
| Chris@1118 | 16 | 
| Chris@1118 | 17 #include <iostream> | 
| Chris@1118 | 18 using namespace std; | 
| Chris@1118 | 19 | 
| Chris@1118 | 20 #define DEBUG_SCROLLABLE_MAG_RANGE_CACHE 1 | 
| Chris@1118 | 21 | 
| Chris@1118 | 22 void | 
| Chris@1118 | 23 ScrollableMagRangeCache::scrollTo(const LayerGeometryProvider *v, | 
| Chris@1118 | 24 				  sv_frame_t newStartFrame) | 
| Chris@1118 | 25 { | 
| Chris@1118 | 26     if (m_startFrame == newStartFrame) { | 
| Chris@1118 | 27 	// haven't moved | 
| Chris@1118 | 28         return; | 
| Chris@1118 | 29     } | 
| Chris@1118 | 30 | 
| Chris@1118 | 31     int dx = (v->getXForFrame(m_startFrame) - | 
| Chris@1118 | 32 	      v->getXForFrame(newStartFrame)); | 
| Chris@1118 | 33 | 
| Chris@1118 | 34 #ifdef DEBUG_SCROLLABLE_MAG_RANGE_CACHE | 
| Chris@1118 | 35     cerr << "ScrollableMagRangeCache::scrollTo: start frame " << m_startFrame | 
| Chris@1118 | 36 	 << " -> " << newStartFrame << ", dx = " << dx << endl; | 
| Chris@1118 | 37 #endif | 
| Chris@1118 | 38 | 
| Chris@1118 | 39     m_startFrame = newStartFrame; | 
| Chris@1118 | 40 | 
| Chris@1118 | 41     if (dx == 0) { | 
| Chris@1118 | 42 	// haven't moved visibly (even though start frame may have changed) | 
| Chris@1118 | 43 	return; | 
| Chris@1118 | 44     } | 
| Chris@1118 | 45 | 
| Chris@1118 | 46     int w = int(m_ranges.size()); | 
| Chris@1118 | 47 | 
| Chris@1118 | 48     if (dx <= -w || dx >= w) { | 
| Chris@1118 | 49 	// scrolled entirely off | 
| Chris@1118 | 50 	invalidate(); | 
| Chris@1118 | 51 	return; | 
| Chris@1118 | 52     } | 
| Chris@1118 | 53 | 
| Chris@1118 | 54     // dx is in range, cache is scrollable | 
| Chris@1118 | 55 | 
| Chris@1118 | 56     if (dx < 0) { | 
| Chris@1118 | 57 	// The new start frame is to the left of the old start | 
| Chris@1118 | 58 	// frame. We need to add some empty ranges at the left (start) | 
| Chris@1118 | 59 	// end and clip the right end. Assemble -dx new values, then | 
| Chris@1118 | 60 	// w+dx old values starting at index 0. | 
| Chris@1118 | 61 | 
| Chris@1118 | 62 	auto newRanges = vector<MagnitudeRange>(-dx); | 
| Chris@1118 | 63 	newRanges.insert(newRanges.end(), | 
| Chris@1118 | 64 			 m_ranges.begin(), m_ranges.begin() + w + dx); | 
| Chris@1118 | 65 	m_ranges = newRanges; | 
| Chris@1118 | 66 | 
| Chris@1118 | 67     } else { | 
| Chris@1118 | 68 	// The new start frame is to the right of the old start | 
| Chris@1118 | 69 	// frame. We want to clip the left (start) end and add some | 
| Chris@1118 | 70 	// empty ranges at the right end. Assemble w-dx old values | 
| Chris@1118 | 71 	// starting at index dx, then dx new values. | 
| Chris@1118 | 72 | 
| Chris@1118 | 73 	auto newRanges = vector<MagnitudeRange>(dx); | 
| Chris@1118 | 74 	newRanges.insert(newRanges.begin(), | 
| Chris@1118 | 75 			 m_ranges.begin() + dx, m_ranges.end()); | 
| Chris@1118 | 76 	m_ranges = newRanges; | 
| Chris@1118 | 77     } | 
| Chris@1118 | 78 } | 
| Chris@1118 | 79 | 
| Chris@1118 | 80 void | 
| Chris@1118 | 81 ScrollableMagRangeCache::sampleColumn(const LayerGeometryProvider *v, | 
| Chris@1118 | 82 				      sv_frame_t frame, | 
| Chris@1118 | 83 				      const MagnitudeRange &r) | 
| Chris@1118 | 84 { | 
| Chris@1118 | 85     int x = (v->getXForFrame(frame) - | 
| Chris@1118 | 86 	     v->getXForFrame(m_startFrame)); | 
| Chris@1118 | 87 | 
| Chris@1118 | 88     if (!in_range_for(m_ranges, x)) { | 
| Chris@1118 | 89 	cerr << "WARNING: ScrollableMagRangeCache::sampleColumn: column " << x | 
| Chris@1118 | 90 	     << " arising from frame " << frame << " is out of range for cache " | 
| Chris@1118 | 91 	     << "of width " << m_ranges.size() << endl; | 
| Chris@1118 | 92     } else { | 
| Chris@1118 | 93 	sampleColumn(x, r); | 
| Chris@1118 | 94     } | 
| Chris@1118 | 95 } | 
| Chris@1118 | 96 |