annotate layer/ScrollableImageCache.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 175d4e15884d
children a34a2a25907c
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@1118 41 m_validLeft(0),
Chris@1118 42 m_validWidth(0),
Chris@1030 43 m_startFrame(0),
Chris@1030 44 m_zoomLevel(0)
Chris@1030 45 {}
Chris@1030 46
Chris@1030 47 void invalidate() {
Chris@1118 48 m_validWidth = 0;
Chris@1030 49 }
Chris@1030 50
Chris@1030 51 bool isValid() const {
Chris@1118 52 return m_validWidth > 0;
Chris@1030 53 }
Chris@1030 54
Chris@1030 55 QSize getSize() const {
Chris@1030 56 return m_image.size();
Chris@1030 57 }
Chris@1118 58
Chris@1118 59 /**
Chris@1118 60 * Set the size of the cache. If the new size differs from the
Chris@1118 61 * current size, the cache is invalidated.
Chris@1118 62 */
Chris@1030 63 void resize(QSize newSize) {
Chris@1079 64 if (getSize() != newSize) {
Chris@1079 65 m_image = QImage(newSize, QImage::Format_ARGB32_Premultiplied);
Chris@1079 66 invalidate();
Chris@1079 67 }
Chris@1030 68 }
Chris@1030 69
Chris@1030 70 int getValidLeft() const {
Chris@1118 71 return m_validLeft;
Chris@1030 72 }
Chris@1030 73
Chris@1030 74 int getValidWidth() const {
Chris@1118 75 return m_validWidth;
Chris@1030 76 }
Chris@1030 77
Chris@1030 78 int getValidRight() const {
Chris@1118 79 return m_validLeft + m_validWidth;
Chris@1030 80 }
Chris@1030 81
Chris@1030 82 QRect getValidArea() const {
Chris@1118 83 return QRect(m_validLeft, 0, m_validWidth, m_image.height());
Chris@1030 84 }
Chris@1030 85
Chris@1030 86 int getZoomLevel() const {
Chris@1030 87 return m_zoomLevel;
Chris@1030 88 }
Chris@1118 89
Chris@1118 90 /**
Chris@1118 91 * Set the zoom level. If the new zoom level differs from the
Chris@1118 92 * current one, the cache is invalidated. (Determining whether to
Chris@1118 93 * invalidate the cache here is the only thing the zoom level is
Chris@1118 94 * used for.)
Chris@1118 95 */
Chris@1031 96 void setZoomLevel(int zoom) {
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@1030 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@1030 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@1031 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@1030 150 int width,
Chris@1030 151 QImage image,
Chris@1030 152 int imageLeft,
Chris@1031 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@1030 160 int m_zoomLevel;
Chris@1030 161 };
Chris@1030 162
Chris@1030 163 #endif