annotate layer/ScrollableImageCache.h @ 1089:c8683d94442a spectrogram-minor-refactor

Start to introduce renderer objects
author Chris Cannam
date Tue, 05 Jul 2016 12:20:56 +0100
parents cbc7c8675706
children c8c747783110
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@1030 27 * A cached image for a view that scrolls horizontally, primarily the
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@1030 40 ScrollableImageCache(const LayerGeometryProvider *v = 0) :
Chris@1030 41 m_v(v),
Chris@1030 42 m_left(0),
Chris@1030 43 m_width(0),
Chris@1030 44 m_startFrame(0),
Chris@1030 45 m_zoomLevel(0)
Chris@1030 46 {}
Chris@1030 47
Chris@1030 48 void invalidate() {
Chris@1030 49 m_width = 0;
Chris@1030 50 }
Chris@1030 51
Chris@1030 52 bool isValid() const {
Chris@1030 53 return m_width > 0;
Chris@1030 54 }
Chris@1030 55
Chris@1030 56 QSize getSize() const {
Chris@1030 57 return m_image.size();
Chris@1030 58 }
Chris@1030 59
Chris@1030 60 void resize(QSize newSize) {
Chris@1079 61 if (getSize() != newSize) {
Chris@1079 62 m_image = QImage(newSize, QImage::Format_ARGB32_Premultiplied);
Chris@1079 63 invalidate();
Chris@1079 64 }
Chris@1030 65 }
Chris@1030 66
Chris@1030 67 int getValidLeft() const {
Chris@1030 68 return m_left;
Chris@1030 69 }
Chris@1030 70
Chris@1030 71 int getValidWidth() const {
Chris@1030 72 return m_width;
Chris@1030 73 }
Chris@1030 74
Chris@1030 75 int getValidRight() const {
Chris@1030 76 return m_left + m_width;
Chris@1030 77 }
Chris@1030 78
Chris@1030 79 QRect getValidArea() const {
Chris@1030 80 return QRect(m_left, 0, m_width, m_image.height());
Chris@1030 81 }
Chris@1030 82
Chris@1030 83 int getZoomLevel() const {
Chris@1030 84 return m_zoomLevel;
Chris@1030 85 }
Chris@1031 86
Chris@1031 87 void setZoomLevel(int zoom) {
Chris@1079 88 if (m_zoomLevel != zoom) {
Chris@1079 89 m_zoomLevel = zoom;
Chris@1079 90 invalidate();
Chris@1079 91 }
Chris@1031 92 }
Chris@1030 93
Chris@1030 94 sv_frame_t getStartFrame() const {
Chris@1030 95 return m_startFrame;
Chris@1030 96 }
Chris@1031 97
Chris@1031 98 /**
Chris@1031 99 * Set the start frame and invalidate the cache. To scroll,
Chris@1031 100 * i.e. to set the start frame while retaining cache validity
Chris@1031 101 * where possible, use scrollTo() instead.
Chris@1031 102 */
Chris@1031 103 void setStartFrame(sv_frame_t frame) {
Chris@1079 104 if (m_startFrame != frame) {
Chris@1079 105 m_startFrame = frame;
Chris@1079 106 invalidate();
Chris@1079 107 }
Chris@1030 108 }
Chris@1030 109
Chris@1030 110 const QImage &getImage() const {
Chris@1030 111 return m_image;
Chris@1030 112 }
Chris@1030 113
Chris@1031 114 /**
Chris@1031 115 * Set the new start frame for the cache, if possible also moving
Chris@1031 116 * along any existing valid data within the cache so that it
Chris@1031 117 * continues to be valid for the new start frame.
Chris@1031 118 */
Chris@1031 119 void scrollTo(sv_frame_t newStartFrame);
Chris@1030 120
Chris@1031 121 /**
Chris@1031 122 * Take a left coordinate and width describing a region, and
Chris@1031 123 * adjust them so that they are contiguous with the cache valid
Chris@1031 124 * region and so that the union of the adjusted region with the
Chris@1081 125 * cache valid region contains the supplied region. Does not
Chris@1081 126 * modify anything about the cache, only about the arguments.
Chris@1031 127 */
Chris@1031 128 void adjustToTouchValidArea(int &left, int &width,
Chris@1031 129 bool &isLeftOfValidArea) const;
Chris@1081 130
Chris@1031 131 /**
Chris@1031 132 * Draw from an image onto the cache. The supplied image must have
Chris@1031 133 * the same height as the cache and the full height is always
Chris@1031 134 * drawn. The left and width parameters determine the target
Chris@1031 135 * region of the cache, the imageLeft and imageWidth parameters
Chris@1031 136 * the source region of the image.
Chris@1031 137 */
Chris@1030 138 void drawImage(int left,
Chris@1030 139 int width,
Chris@1030 140 QImage image,
Chris@1030 141 int imageLeft,
Chris@1031 142 int imageWidth);
Chris@1030 143
Chris@1030 144 private:
Chris@1030 145 const LayerGeometryProvider *m_v;
Chris@1030 146 QImage m_image;
Chris@1030 147 int m_left; // of valid region
Chris@1030 148 int m_width; // of valid region
Chris@1030 149 sv_frame_t m_startFrame;
Chris@1030 150 int m_zoomLevel;
Chris@1030 151 };
Chris@1030 152
Chris@1030 153 #endif