comparison layer/ScrollableImageCache.h @ 1216:dc2af6616c83

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