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
|