annotate layer/ScrollableImageCache.h @ 1417:2487521e857b

Merge
author Chris Cannam
date Wed, 23 Jan 2019 14:44:16 +0000
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