annotate layer/ScrollableImageCache.h @ 1548:bd6af89982d7

Permit getScaleProvidingLayerForUnit to return a dormant layer if there is no visible alternative. This is necessary to avoid the scale disappearing in Tony when the spectrogram is toggled off.
author Chris Cannam
date Thu, 17 Oct 2019 14:44:22 +0100
parents bc2cb82050a0
children
rev   line source
Chris@1030 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@1030 2
Chris@1030 3 /*
Chris@1030 4 Sonic Visualiser
Chris@1030 5 An audio file viewer and annotation editor.
Chris@1030 6 Centre for Digital Music, Queen Mary, University of London.
Chris@1030 7
Chris@1030 8 This program is free software; you can redistribute it and/or
Chris@1030 9 modify it under the terms of the GNU General Public License as
Chris@1030 10 published by the Free Software Foundation; either version 2 of the
Chris@1030 11 License, or (at your option) any later version. See the file
Chris@1030 12 COPYING included with this distribution for more information.
Chris@1030 13 */
Chris@1030 14
Chris@1030 15 #ifndef SCROLLABLE_IMAGE_CACHE_H
Chris@1030 16 #define SCROLLABLE_IMAGE_CACHE_H
Chris@1030 17
Chris@1030 18 #include "base/BaseTypes.h"
Chris@1030 19
Chris@1077 20 #include "LayerGeometryProvider.h"
Chris@1030 21
Chris@1030 22 #include <QImage>
Chris@1030 23 #include <QRect>
Chris@1030 24 #include <QPainter>
Chris@1030 25
Chris@1030 26 /**
Chris@1118 27 * A cached image for a view that scrolls horizontally, such as a
Chris@1030 28 * spectrogram. The cache object holds an image, reports the size of
Chris@1030 29 * the image (likely the same as the underlying view, but it's the
Chris@1030 30 * caller's responsibility to set the size appropriately), can scroll
Chris@1030 31 * the image, and can report and update which contiguous horizontal
Chris@1030 32 * range of the image is valid.
Chris@1030 33 *
Chris@1030 34 * The only way to *update* the valid area in a cache is to draw to it
Chris@1030 35 * using the drawImage call.
Chris@1030 36 */
Chris@1030 37 class ScrollableImageCache
Chris@1030 38 {
Chris@1030 39 public:
Chris@1090 40 ScrollableImageCache() :
Chris@1266 41 m_validLeft(0),
Chris@1266 42 m_validWidth(0),
Chris@1325 43 m_startFrame(0)
Chris@1030 44 {}
Chris@1030 45
Chris@1030 46 void invalidate() {
Chris@1266 47 m_validWidth = 0;
Chris@1030 48 }
Chris@1030 49
Chris@1030 50 bool isValid() const {
Chris@1266 51 return m_validWidth > 0;
Chris@1030 52 }
Chris@1030 53
Chris@1030 54 QSize getSize() const {
Chris@1266 55 return m_image.size();
Chris@1030 56 }
Chris@1118 57
Chris@1118 58 /**
Chris@1118 59 * Set the size of the cache. If the new size differs from the
Chris@1118 60 * current size, the cache is invalidated.
Chris@1118 61 */
Chris@1030 62 void resize(QSize newSize) {
Chris@1079 63 if (getSize() != newSize) {
Chris@1079 64 m_image = QImage(newSize, QImage::Format_ARGB32_Premultiplied);
Chris@1079 65 invalidate();
Chris@1079 66 }
Chris@1030 67 }
Chris@1266 68
Chris@1030 69 int getValidLeft() const {
Chris@1266 70 return m_validLeft;
Chris@1030 71 }
Chris@1030 72
Chris@1030 73 int getValidWidth() const {
Chris@1266 74 return m_validWidth;
Chris@1030 75 }
Chris@1030 76
Chris@1030 77 int getValidRight() const {
Chris@1266 78 return m_validLeft + m_validWidth;
Chris@1030 79 }
Chris@1030 80
Chris@1030 81 QRect getValidArea() const {
Chris@1266 82 return QRect(m_validLeft, 0, m_validWidth, m_image.height());
Chris@1030 83 }
Chris@1030 84
Chris@1325 85 ZoomLevel getZoomLevel() const {
Chris@1266 86 return m_zoomLevel;
Chris@1030 87 }
Chris@1118 88
Chris@1118 89 /**
Chris@1118 90 * Set the zoom level. If the new zoom level differs from the
Chris@1118 91 * current one, the cache is invalidated. (Determining whether to
Chris@1118 92 * invalidate the cache here is the only thing the zoom level is
Chris@1118 93 * used for.)
Chris@1118 94 */
Chris@1325 95 void setZoomLevel(ZoomLevel zoom) {
Chris@1325 96 using namespace std::rel_ops;
Chris@1079 97 if (m_zoomLevel != zoom) {
Chris@1079 98 m_zoomLevel = zoom;
Chris@1079 99 invalidate();
Chris@1079 100 }
Chris@1031 101 }
Chris@1030 102
Chris@1030 103 sv_frame_t getStartFrame() const {
Chris@1266 104 return m_startFrame;
Chris@1030 105 }
Chris@1031 106
Chris@1031 107 /**
Chris@1118 108 * Set the start frame. If the new start frame differs from the
Chris@1118 109 * current one, the cache is invalidated. To scroll, i.e. to set
Chris@1118 110 * the start frame while retaining cache validity where possible,
Chris@1118 111 * use scrollTo() instead.
Chris@1031 112 */
Chris@1031 113 void setStartFrame(sv_frame_t frame) {
Chris@1079 114 if (m_startFrame != frame) {
Chris@1079 115 m_startFrame = frame;
Chris@1079 116 invalidate();
Chris@1079 117 }
Chris@1030 118 }
Chris@1030 119
Chris@1030 120 const QImage &getImage() const {
Chris@1266 121 return m_image;
Chris@1030 122 }
Chris@1030 123
Chris@1031 124 /**
Chris@1090 125 * Set the new start frame for the cache, according to the
Chris@1090 126 * geometry of the supplied LayerGeometryProvider, if possible
Chris@1090 127 * also moving along any existing valid data within the cache so
Chris@1090 128 * that it continues to be valid for the new start frame.
Chris@1031 129 */
Chris@1113 130 void scrollTo(const LayerGeometryProvider *v, sv_frame_t newStartFrame);
Chris@1030 131
Chris@1031 132 /**
Chris@1031 133 * Take a left coordinate and width describing a region, and
Chris@1031 134 * adjust them so that they are contiguous with the cache valid
Chris@1031 135 * region and so that the union of the adjusted region with the
Chris@1081 136 * cache valid region contains the supplied region. Does not
Chris@1081 137 * modify anything about the cache, only about the arguments.
Chris@1031 138 */
Chris@1031 139 void adjustToTouchValidArea(int &left, int &width,
Chris@1266 140 bool &isLeftOfValidArea) const;
Chris@1081 141
Chris@1031 142 /**
Chris@1031 143 * Draw from an image onto the cache. The supplied image must have
Chris@1031 144 * the same height as the cache and the full height is always
Chris@1031 145 * drawn. The left and width parameters determine the target
Chris@1031 146 * region of the cache, the imageLeft and imageWidth parameters
Chris@1031 147 * the source region of the image.
Chris@1031 148 */
Chris@1030 149 void drawImage(int left,
Chris@1266 150 int width,
Chris@1266 151 QImage image,
Chris@1266 152 int imageLeft,
Chris@1266 153 int imageWidth);
Chris@1030 154
Chris@1030 155 private:
Chris@1030 156 QImage m_image;
Chris@1118 157 int m_validLeft;
Chris@1118 158 int m_validWidth;
Chris@1030 159 sv_frame_t m_startFrame;
Chris@1325 160 ZoomLevel m_zoomLevel;
Chris@1030 161 };
Chris@1030 162
Chris@1030 163 #endif