Mercurial > hg > svgui
diff layer/ScrollableMagRangeCache.h @ 1216:dc2af6616c83
Merge from branch 3.0-integration
author | Chris Cannam |
---|---|
date | Fri, 13 Jan 2017 10:29:50 +0000 |
parents | c53ed1a6fcbd |
children | a34a2a25907c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layer/ScrollableMagRangeCache.h Fri Jan 13 10:29:50 2017 +0000 @@ -0,0 +1,139 @@ +/* -*- 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" + +/** + * 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), + m_zoomLevel(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); + } + } + + int 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(int zoom) { + 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; + int m_zoomLevel; +}; + +#endif