annotate layer/ScrollableImageCache.h @ 1064:77564d4fff43 spectrogram-minor-refactor

Extend column logic to peak frequency display as well, and correct some scopes according to whether values are per source column or per target pixel
author Chris Cannam
date Mon, 20 Jun 2016 12:00:32 +0100
parents 55ac6ac1982e
children 5144d7185fb5
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@1030 20 #include "view/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@1030 61 m_image = QImage(newSize, QImage::Format_ARGB32_Premultiplied);
Chris@1030 62 invalidate();
Chris@1030 63 }
Chris@1030 64
Chris@1030 65 int getValidLeft() const {
Chris@1030 66 return m_left;
Chris@1030 67 }
Chris@1030 68
Chris@1030 69 int getValidWidth() const {
Chris@1030 70 return m_width;
Chris@1030 71 }
Chris@1030 72
Chris@1030 73 int getValidRight() const {
Chris@1030 74 return m_left + m_width;
Chris@1030 75 }
Chris@1030 76
Chris@1030 77 QRect getValidArea() const {
Chris@1030 78 return QRect(m_left, 0, m_width, m_image.height());
Chris@1030 79 }
Chris@1030 80
Chris@1030 81 int getZoomLevel() const {
Chris@1030 82 return m_zoomLevel;
Chris@1030 83 }
Chris@1031 84
Chris@1031 85 void setZoomLevel(int zoom) {
Chris@1031 86 m_zoomLevel = zoom;
Chris@1031 87 invalidate();
Chris@1031 88 }
Chris@1030 89
Chris@1030 90 sv_frame_t getStartFrame() const {
Chris@1030 91 return m_startFrame;
Chris@1030 92 }
Chris@1031 93
Chris@1031 94 /**
Chris@1031 95 * Set the start frame and invalidate the cache. To scroll,
Chris@1031 96 * i.e. to set the start frame while retaining cache validity
Chris@1031 97 * where possible, use scrollTo() instead.
Chris@1031 98 */
Chris@1031 99 void setStartFrame(sv_frame_t frame) {
Chris@1031 100 m_startFrame = frame;
Chris@1030 101 invalidate();
Chris@1030 102 }
Chris@1030 103
Chris@1030 104 const QImage &getImage() const {
Chris@1030 105 return m_image;
Chris@1030 106 }
Chris@1030 107
Chris@1031 108 /**
Chris@1031 109 * Set the new start frame for the cache, if possible also moving
Chris@1031 110 * along any existing valid data within the cache so that it
Chris@1031 111 * continues to be valid for the new start frame.
Chris@1031 112 */
Chris@1031 113 void scrollTo(sv_frame_t newStartFrame);
Chris@1030 114
Chris@1031 115 /**
Chris@1031 116 * Take a left coordinate and width describing a region, and
Chris@1031 117 * adjust them so that they are contiguous with the cache valid
Chris@1031 118 * region and so that the union of the adjusted region with the
Chris@1031 119 * cache valid region contains the supplied region.
Chris@1031 120 */
Chris@1031 121 void adjustToTouchValidArea(int &left, int &width,
Chris@1031 122 bool &isLeftOfValidArea) const;
Chris@1031 123 /**
Chris@1031 124 * Draw from an image onto the cache. The supplied image must have
Chris@1031 125 * the same height as the cache and the full height is always
Chris@1031 126 * drawn. The left and width parameters determine the target
Chris@1031 127 * region of the cache, the imageLeft and imageWidth parameters
Chris@1031 128 * the source region of the image.
Chris@1031 129 */
Chris@1030 130 void drawImage(int left,
Chris@1030 131 int width,
Chris@1030 132 QImage image,
Chris@1030 133 int imageLeft,
Chris@1031 134 int imageWidth);
Chris@1030 135
Chris@1030 136 private:
Chris@1030 137 const LayerGeometryProvider *m_v;
Chris@1030 138 QImage m_image;
Chris@1030 139 int m_left; // of valid region
Chris@1030 140 int m_width; // of valid region
Chris@1030 141 sv_frame_t m_startFrame;
Chris@1030 142 int m_zoomLevel;
Chris@1030 143 };
Chris@1030 144
Chris@1030 145 #endif