annotate layer/ScrollableMagRangeCache.h @ 1204:d421df27e184 3.0-integration

Further PropertyBox layout overhaul: avoid crash (/ assertion failure) when property type changes from e.g. colour to colourmap, by replacing the existing widget within the layout rather than trying to repopulate it
author Chris Cannam
date Tue, 20 Dec 2016 10:49:24 +0000
parents c53ed1a6fcbd
children a34a2a25907c
rev   line source
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@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@1118 136 int m_zoomLevel;
Chris@1118 137 };
Chris@1118 138
Chris@1118 139 #endif