File: ScrollableMagRangeCache.h

package info (click to toggle)
sonic-visualiser 5.2.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 24,744 kB
  • sloc: cpp: 158,888; ansic: 11,920; sh: 1,785; makefile: 517; xml: 64; perl: 31
file content (143 lines) | stat: -rw-r--r-- 4,239 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */

/*
    Sonic Visualiser
    An audio file viewer and annotation editor.
    Centre for Digital Music, Queen Mary, University of London.
    
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.  See the file
    COPYING included with this distribution for more information.
*/

#ifndef SCROLLABLE_MAG_RANGE_CACHE_H
#define SCROLLABLE_MAG_RANGE_CACHE_H

#include "base/BaseTypes.h"
#include "base/MagnitudeRange.h"

#include "LayerGeometryProvider.h"

namespace sv {

/**
 * A cached set of magnitude range records for a view that scrolls
 * horizontally, such as a spectrogram. The cache object holds a
 * magnitude range per column of the view, can report width (likely
 * the same as the underlying view, but it's the caller's
 * responsibility to set the size appropriately), can scroll the set
 * of ranges, and can report and update which columns have had a range
 * specified.
 *
 * The only way to *update* the valid area in a cache is to update the
 * magnitude range for a column using the sampleColumn call.
 */
class ScrollableMagRangeCache
{
public:
    ScrollableMagRangeCache() :
        m_startFrame(0)
    {}

    void invalidate() {
        m_ranges = std::vector<MagnitudeRange>(m_ranges.size());
    }
    
    int getWidth() const {
        return int(m_ranges.size());
    }

    /**
     * Set the width of the cache in columns. If the new size differs
     * from the current size, the cache is invalidated.
     */
    void resize(int newWidth) {
        if (getWidth() != newWidth) {
            m_ranges = std::vector<MagnitudeRange>(newWidth);
        }
    }
        
    ZoomLevel getZoomLevel() const {
        return m_zoomLevel;
    }

    /**
     * Set the zoom level. If the new zoom level differs from the
     * current one, the cache is invalidated. (Determining whether to
     * invalidate the cache here is the only thing the zoom level is
     * used for.)
     */
    void setZoomLevel(ZoomLevel zoom) {
        using namespace std::rel_ops;
        if (m_zoomLevel != zoom) {
            m_zoomLevel = zoom;
            invalidate();
        }
    }

    sv_frame_t getStartFrame() const {
        return m_startFrame;
    }

    /**
     * Set the start frame. If the new start frame differs from the
     * current one, the cache is invalidated. To scroll, i.e. to set
     * the start frame while retaining cache validity where possible,
     * use scrollTo() instead.
     */
    void setStartFrame(sv_frame_t frame) {
        if (m_startFrame != frame) {
            m_startFrame = frame;
            invalidate();
        }
    }

    bool isColumnSet(int column) const {
        return in_range_for(m_ranges, column) && m_ranges.at(column).isSet();
    }

    bool areColumnsSet(int x, int count) const {
        for (int i = 0; i < count; ++i) {
            if (!isColumnSet(x + i)) return false;
        }
        return true;
    }
    
    /**
     * Get the magnitude range for a single column.
     */
    MagnitudeRange getRange(int column) const {
        return m_ranges.at(column);
    }

    /**
     * Get the magnitude range for a range of columns.
     */
    MagnitudeRange getRange(int x, int count) const;
    
    /**
     * Set the new start frame for the cache, according to the
     * geometry of the supplied LayerGeometryProvider, if possible
     * also moving along any existing valid data within the cache so
     * that it continues to be valid for the new start frame.
     */
    void scrollTo(const LayerGeometryProvider *v, sv_frame_t newStartFrame);
    
    /**
     * Update a column in the cache, by column index. (Column zero is
     * the first column in the cache, it has nothing to do with any
     * underlying model that the cache may be used with.)
     */
    void sampleColumn(int column, const MagnitudeRange &r);
    
private:
    std::vector<MagnitudeRange> m_ranges;
    sv_frame_t m_startFrame;
    ZoomLevel m_zoomLevel;
};

} // end namespace sv

#endif