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@1118
|
39 m_startFrame(0),
|
Chris@1118
|
40 m_zoomLevel(0)
|
Chris@1118
|
41 {}
|
Chris@1118
|
42
|
Chris@1118
|
43 void invalidate() {
|
Chris@1118
|
44 m_ranges = std::vector<MagnitudeRange>(m_ranges.size());
|
Chris@1118
|
45 }
|
Chris@1118
|
46
|
Chris@1118
|
47 int getWidth() const {
|
Chris@1118
|
48 return int(m_ranges.size());
|
Chris@1118
|
49 }
|
Chris@1118
|
50
|
Chris@1118
|
51 /**
|
Chris@1118
|
52 * Set the width of the cache in columns. If the new size differs
|
Chris@1118
|
53 * from the current size, the cache is invalidated.
|
Chris@1118
|
54 */
|
Chris@1118
|
55 void resize(int newWidth) {
|
Chris@1118
|
56 if (getWidth() != newWidth) {
|
Chris@1118
|
57 m_ranges = std::vector<MagnitudeRange>(newWidth);
|
Chris@1118
|
58 }
|
Chris@1118
|
59 }
|
Chris@1118
|
60
|
Chris@1118
|
61 int getZoomLevel() const {
|
Chris@1118
|
62 return m_zoomLevel;
|
Chris@1118
|
63 }
|
Chris@1118
|
64
|
Chris@1118
|
65 /**
|
Chris@1118
|
66 * Set the zoom level. If the new zoom level differs from the
|
Chris@1118
|
67 * current one, the cache is invalidated. (Determining whether to
|
Chris@1118
|
68 * invalidate the cache here is the only thing the zoom level is
|
Chris@1118
|
69 * used for.)
|
Chris@1118
|
70 */
|
Chris@1118
|
71 void setZoomLevel(int zoom) {
|
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@1118
|
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@1118
|
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@1119
|
100 for (int i = 0; i < count; ++i) {
|
Chris@1119
|
101 if (!isColumnSet(x + i)) return false;
|
Chris@1119
|
102 }
|
Chris@1119
|
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@1118
|
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@1119
|
116 MagnitudeRange getRange(int x, int count) const {
|
Chris@1119
|
117 MagnitudeRange r;
|
Chris@1119
|
118 for (int i = 0; i < count; ++i) {
|
Chris@1119
|
119 r.sample(m_ranges.at(x + i));
|
Chris@1119
|
120 }
|
Chris@1119
|
121 return r;
|
Chris@1119
|
122 }
|
Chris@1119
|
123
|
Chris@1119
|
124 /**
|
Chris@1118
|
125 * Set the new start frame for the cache, according to the
|
Chris@1118
|
126 * geometry of the supplied LayerGeometryProvider, if possible
|
Chris@1118
|
127 * also moving along any existing valid data within the cache so
|
Chris@1118
|
128 * that it continues to be valid for the new start frame.
|
Chris@1118
|
129 */
|
Chris@1118
|
130 void scrollTo(const LayerGeometryProvider *v, sv_frame_t newStartFrame);
|
Chris@1118
|
131
|
Chris@1118
|
132 /**
|
Chris@1120
|
133 * Update a column in the cache, by column index. (Column zero is
|
Chris@1120
|
134 * the first column in the cache, it has nothing to do with any
|
Chris@1120
|
135 * underlying model that the cache may be used with.)
|
Chris@1118
|
136 */
|
Chris@1120
|
137 void sampleColumn(int column, const MagnitudeRange &r);
|
Chris@1118
|
138
|
Chris@1118
|
139 /**
|
Chris@1118
|
140 * Update a column in the cache, by frame.
|
Chris@1118
|
141 */
|
Chris@1118
|
142 void sampleColumn(const LayerGeometryProvider *v, sv_frame_t frame,
|
Chris@1118
|
143 const MagnitudeRange &r);
|
Chris@1118
|
144
|
Chris@1118
|
145 private:
|
Chris@1118
|
146 std::vector<MagnitudeRange> m_ranges;
|
Chris@1118
|
147 sv_frame_t m_startFrame;
|
Chris@1118
|
148 int m_zoomLevel;
|
Chris@1118
|
149 };
|
Chris@1118
|
150
|
Chris@1118
|
151 #endif
|