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 #ifndef SCROLLABLE_MAG_RANGE_CACHE_H
|
Chris@1118
|
16 #define SCROLLABLE_MAG_RANGE_CACHE_H
|
Chris@1118
|
17
|
Chris@1118
|
18 #include "base/BaseTypes.h"
|
Chris@1118
|
19 #include "base/MagnitudeRange.h"
|
Chris@1118
|
20
|
Chris@1118
|
21 #include "LayerGeometryProvider.h"
|
Chris@1118
|
22
|
Chris@1118
|
23 /**
|
Chris@1118
|
24 * A cached set of magnitude range records for a view that scrolls
|
Chris@1118
|
25 * horizontally, such as a spectrogram. The cache object holds a
|
Chris@1118
|
26 * magnitude range per column of the view, can report width (likely
|
Chris@1118
|
27 * the same as the underlying view, but it's the caller's
|
Chris@1118
|
28 * responsibility to set the size appropriately), can scroll the set
|
Chris@1118
|
29 * of ranges, and can report and update which columns have had a range
|
Chris@1118
|
30 * specified.
|
Chris@1118
|
31 *
|
Chris@1118
|
32 * The only way to *update* the valid area in a cache is to update the
|
Chris@1118
|
33 * magnitude range for a column using the sampleColumn call.
|
Chris@1118
|
34 */
|
Chris@1118
|
35 class ScrollableMagRangeCache
|
Chris@1118
|
36 {
|
Chris@1118
|
37 public:
|
Chris@1118
|
38 ScrollableMagRangeCache() :
|
Chris@1325
|
39 m_startFrame(0)
|
Chris@1118
|
40 {}
|
Chris@1118
|
41
|
Chris@1118
|
42 void invalidate() {
|
Chris@1266
|
43 m_ranges = std::vector<MagnitudeRange>(m_ranges.size());
|
Chris@1118
|
44 }
|
Chris@1118
|
45
|
Chris@1118
|
46 int getWidth() const {
|
Chris@1266
|
47 return int(m_ranges.size());
|
Chris@1118
|
48 }
|
Chris@1118
|
49
|
Chris@1118
|
50 /**
|
Chris@1118
|
51 * Set the width of the cache in columns. If the new size differs
|
Chris@1118
|
52 * from the current size, the cache is invalidated.
|
Chris@1118
|
53 */
|
Chris@1118
|
54 void resize(int newWidth) {
|
Chris@1118
|
55 if (getWidth() != newWidth) {
|
Chris@1266
|
56 m_ranges = std::vector<MagnitudeRange>(newWidth);
|
Chris@1118
|
57 }
|
Chris@1118
|
58 }
|
Chris@1266
|
59
|
Chris@1325
|
60 ZoomLevel getZoomLevel() const {
|
Chris@1266
|
61 return m_zoomLevel;
|
Chris@1118
|
62 }
|
Chris@1118
|
63
|
Chris@1118
|
64 /**
|
Chris@1118
|
65 * Set the zoom level. If the new zoom level differs from the
|
Chris@1118
|
66 * current one, the cache is invalidated. (Determining whether to
|
Chris@1118
|
67 * invalidate the cache here is the only thing the zoom level is
|
Chris@1118
|
68 * used for.)
|
Chris@1118
|
69 */
|
Chris@1325
|
70 void setZoomLevel(ZoomLevel zoom) {
|
Chris@1325
|
71 using namespace std::rel_ops;
|
Chris@1118
|
72 if (m_zoomLevel != zoom) {
|
Chris@1118
|
73 m_zoomLevel = zoom;
|
Chris@1118
|
74 invalidate();
|
Chris@1118
|
75 }
|
Chris@1118
|
76 }
|
Chris@1118
|
77
|
Chris@1118
|
78 sv_frame_t getStartFrame() const {
|
Chris@1266
|
79 return m_startFrame;
|
Chris@1118
|
80 }
|
Chris@1118
|
81
|
Chris@1118
|
82 /**
|
Chris@1118
|
83 * Set the start frame. If the new start frame differs from the
|
Chris@1118
|
84 * current one, the cache is invalidated. To scroll, i.e. to set
|
Chris@1118
|
85 * the start frame while retaining cache validity where possible,
|
Chris@1118
|
86 * use scrollTo() instead.
|
Chris@1118
|
87 */
|
Chris@1118
|
88 void setStartFrame(sv_frame_t frame) {
|
Chris@1118
|
89 if (m_startFrame != frame) {
|
Chris@1118
|
90 m_startFrame = frame;
|
Chris@1118
|
91 invalidate();
|
Chris@1118
|
92 }
|
Chris@1118
|
93 }
|
Chris@1118
|
94
|
Chris@1118
|
95 bool isColumnSet(int column) const {
|
Chris@1266
|
96 return in_range_for(m_ranges, column) && m_ranges.at(column).isSet();
|
Chris@1118
|
97 }
|
Chris@1119
|
98
|
Chris@1119
|
99 bool areColumnsSet(int x, int count) const {
|
Chris@1266
|
100 for (int i = 0; i < count; ++i) {
|
Chris@1266
|
101 if (!isColumnSet(x + i)) return false;
|
Chris@1266
|
102 }
|
Chris@1266
|
103 return true;
|
Chris@1119
|
104 }
|
Chris@1118
|
105
|
Chris@1119
|
106 /**
|
Chris@1119
|
107 * Get the magnitude range for a single column.
|
Chris@1119
|
108 */
|
Chris@1119
|
109 MagnitudeRange getRange(int column) const {
|
Chris@1266
|
110 return m_ranges.at(column);
|
Chris@1118
|
111 }
|
Chris@1118
|
112
|
Chris@1118
|
113 /**
|
Chris@1119
|
114 * Get the magnitude range for a range of columns.
|
Chris@1119
|
115 */
|
Chris@1122
|
116 MagnitudeRange getRange(int x, int count) const;
|
Chris@1119
|
117
|
Chris@1119
|
118 /**
|
Chris@1118
|
119 * Set the new start frame for the cache, according to the
|
Chris@1118
|
120 * geometry of the supplied LayerGeometryProvider, if possible
|
Chris@1118
|
121 * also moving along any existing valid data within the cache so
|
Chris@1118
|
122 * that it continues to be valid for the new start frame.
|
Chris@1118
|
123 */
|
Chris@1118
|
124 void scrollTo(const LayerGeometryProvider *v, sv_frame_t newStartFrame);
|
Chris@1118
|
125
|
Chris@1118
|
126 /**
|
Chris@1120
|
127 * Update a column in the cache, by column index. (Column zero is
|
Chris@1120
|
128 * the first column in the cache, it has nothing to do with any
|
Chris@1120
|
129 * underlying model that the cache may be used with.)
|
Chris@1118
|
130 */
|
Chris@1120
|
131 void sampleColumn(int column, const MagnitudeRange &r);
|
Chris@1118
|
132
|
Chris@1118
|
133 private:
|
Chris@1118
|
134 std::vector<MagnitudeRange> m_ranges;
|
Chris@1118
|
135 sv_frame_t m_startFrame;
|
Chris@1325
|
136 ZoomLevel m_zoomLevel;
|
Chris@1118
|
137 };
|
Chris@1118
|
138
|
Chris@1118
|
139 #endif
|