annotate layer/ScrollableMagRangeCache.h @ 1314:769d7890203b

Layers such as time-value layers with ColourDistinguishes property should use the dark background when a bright colour is selected. This is how it was always supposed to work, I think, but I broke it so long ago that this "fix" might itself come across as a surprising breaking change
author Chris Cannam
date Wed, 04 Jul 2018 15:33:47 +0100
parents a34a2a25907c
children bc2cb82050a0
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@1266 39 m_startFrame(0),
Chris@1266 40 m_zoomLevel(0)
Chris@1118 41 {}
Chris@1118 42
Chris@1118 43 void invalidate() {
Chris@1266 44 m_ranges = std::vector<MagnitudeRange>(m_ranges.size());
Chris@1118 45 }
Chris@1118 46
Chris@1118 47 int getWidth() const {
Chris@1266 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@1266 57 m_ranges = std::vector<MagnitudeRange>(newWidth);
Chris@1118 58 }
Chris@1118 59 }
Chris@1266 60
Chris@1118 61 int getZoomLevel() const {
Chris@1266 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@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@1118 136 int m_zoomLevel;
Chris@1118 137 };
Chris@1118 138
Chris@1118 139 #endif